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