1# 图形图像开发常见问题 2 3 4## 如何获取设备的dpi值(API 9) 5 6**解决措施** 7 8导入\@ohos.display包,通过getDefaultDisplaySync()方法获取。 9 10**代码示例** 11 12``` 13import display from '@ohos.display'; 14let displayClass = null; 15try { 16 displayClass = display.getDefaultDisplaySync(); 17 console.info('Test densityDPI:' + JSON.stringify(displayClass.densityDPI)); 18} catch (exception) { 19 console.error('Failed to obtain the default display object. Code: ' + JSON.stringify(exception)); 20} 21``` 22 23 24## 如何获取窗口的宽高信息(API 9) 25 26**解决措施** 27 28引入窗口模块\@ohos.window,获取指定窗口对象Window后,在该对象上使用getWindowProperties()获取窗口各个属性,在属性windowRect中获取窗口宽高信息。 29如果要在页面中获取窗口宽高信息,需要注意获取的正确时机。页面生命周期[aboutToAppear](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#abouttoappear)阶段,不代表此时窗口可见,仅代表当前组件已创建,此时获取到的窗口尺寸信息(windowRect)可能有误。建议在页面生命周期[onPageShow](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpageshow)阶段获取,该阶段会在窗口可见后调用,此时可以拿到窗口正确的宽高信息。 30 31**代码示例** 32 33``` 34import window from '@ohos.window'; 35 36//如果需要在页面中获取窗口宽高信息,建议将以下代码放在页面生命周期onPageShow阶段,不要在页面生命周期aboutToAppear阶段中调用 37let windowClass = null; 38try { 39 let promise = window.getLastWindow(this.context); 40 promise.then((data)=> { 41 //获取窗口对象 42 windowClass = data; 43 try { 44 //获取窗口属性 45 let properties = windowClass.getWindowProperties(); 46 let rect = properties.windowRect; 47 //rect.width: 窗口宽度;rect.height: 窗口高度 48 } catch (exception) { 49 console.error('Failed to obtain the window properties. Cause: ' + JSON.stringify(exception)); 50 } 51 console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)); 52 }).catch((err)=>{ 53 console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err)); 54 });} catch (exception) { 55 console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception)); 56} 57``` 58 59 60## 如何对图片进行高斯模糊处理(API 9) 61 62**解决措施** 63 64导入图像处理(\@ohos.multimedia.image)和图像效果(\@ohos.effectKit)模块,对图像进行处理并添加模糊效果。 65 66**代码示例** 67 68``` 69import image from "@ohos.multimedia.image"; 70import effectKit from "@ohos.effectKit"; 71 72 const color = new ArrayBuffer(96); 73 let opts = { editable: true, pixelFormat: 3, size: { height: 4, width: 6 } }; 74 image.createPixelMap(color, opts).then((pixelMap) => { 75 let radius = 5; 76 let headFilter = effectKit.createEffect(pixelMap); 77 if (headFilter != null) { 78 headFilter.blur(radius); 79 } 80 }) 81``` 82**参考链接:** 83 84[图片添加模糊效果](../reference/apis-arkgraphics2d/js-apis-effectKit.md#blur) 85 86 87## EGL绘制操作是否只能在主线程,可以放子线程中执行吗(API 10) 88 89**解决措施** 90 91EGL操作可以在子线程中操作,可以通过创建SharedContext,实现EGL在子线程中操作。创建SharedContext示例代码如下。 92 93**代码示例** 94```cpp 95void CreateShareEglContext() 96{ 97 if (renderContext == nullptr) { // renderContext是主线程context 98 RS_LOGE("renderContext_ is nullptr"); 99 return; 100 } 101 eglShareContext = renderContext->CreateShareContext(); 102 if (eglShareContext == EGL_NO_CONTEXT) { 103 RS_LOGE("eglShareContext is EGL_NO_CONTEXT"); 104 return; 105 } 106 if (!eglMakeCurrent(renderContext->GetEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, eglShareContext)) { 107 RS_LOGE("eglMakeCurrent failed"); 108 return; 109 } 110} 111``` 112 113## 如何使用EGL绘制自定义动画(API 10) 114 115**解决措施** 116 117自定义动画需要开发者自主实现,可以采用OpenGL进行绘制。 118关于动画的实现主要是业务方的逻辑,首先业务方需要识别动画触发事件,根据业务诉求获取动画的起点和终点。 119然后根据时间轴和动画曲线计算每一帧的绘制内容。最后调用OpenGL的接口绘制这部分内容。 120 121**参考链接:** 122 123[Native XComponent组件的使用(ArkTS)](https://gitee.com/openharmony/codelabs/tree/master/NativeAPI/XComponent) 124 125## 如何在EGL多线程绘制的场景下同时操作一块buffer进行图形绘制(API 10) 126 127**解决措施** 128 129可以通过每个线程各自产生一块纹理,再将这些纹理合成到一块buffer。 130可以使用sharedContext,实现EGL在子线程中操作。另外绘制操作可通过调用OpenGL实现。 131 132**代码示例** 133```cpp 134void CreateShareEglContext() 135{ 136 if (renderContext == nullptr) { // renderContext是主线程context 137 RS_LOGE("renderContext_ is nullptr"); 138 return; 139 } 140 eglShareContext = renderContext->CreateShareContext(); 141 if (eglShareContext == EGL_NO_CONTEXT) { 142 RS_LOGE("eglShareContext is EGL_NO_CONTEXT"); 143 return; 144 } 145 if (!eglMakeCurrent(renderContext->GetEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, eglShareContext)) { 146 RS_LOGE("eglMakeCurrent failed"); 147 return; 148 } 149} 150``` 151## 从一个Ability跳转到另外一个Ability时,是否支持自定义转场动画的设置,如何实现(API 10) 152 153**解决措施** 154 155不支持,UIAbility会在多任务界面只显示一个卡片,为了动效一致性,不开放给开发者定制。 156UIAbility不能用来组合应用内界面,用应用内导航组件Navigation来实现应用内的跳转。 157 158**参考链接:** 159 160[Navigation的使用](../ui/arkts-navigation-navigation.md) 161 162 163 164 165