• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 复杂绘制效果(C/C++)
2
3
4除了基础填充颜色、描边颜色和一些样式设置的绘制效果外,还支持通过画刷和画笔实现更多复杂的绘制效果。比如:
5
6
7- 混合模式。
8
9- 路径效果,如虚线效果。
10
11- 着色器效果,如线性渐变、径向渐变等。
12
13- 滤波效果,如模糊效果等。
14
15
16## 混合模式
17
18混合模式可以用于画笔或画刷,它定义了如何将源像素(要绘制的内容)与目标像素(已存在于画布上的内容)进行组合。
19
20可以使用OH_Drawing_BrushSetBlendMode()接口将混合模式应用于画刷中,使用OH_Drawing_PenSetBlendMode接口将混合模式应用于画笔中。这两个接口都需要接受一个参数OH_Drawing_BlendMode,即混合模式的类型,具体可参考[BlendMode](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blendmode)。
21
22此处以使用画刷设置叠加混合模式为例(为了防止混合模式的效果被背景色干扰,示例中的canvas并未设置背景色,使用的是默认的黑色背景),关键示例和效果示意图如下所示:
23
24```c++
25// 创建画刷对象
26OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
27// 设置目标像素颜色
28OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
29// 将目标像素的画刷效果设置到Canvas中
30OH_Drawing_CanvasAttachBrush(canvas, brush);
31// 创建矩形对象
32OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 600, 600);
33// 绘制矩形(目标像素)
34OH_Drawing_CanvasDrawRect(canvas, rect);
35// 设置源像素颜色
36OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0xFF));
37// 设置混合模式为叠加模式
38OH_Drawing_BrushSetBlendMode(brush, OH_Drawing_BlendMode::BLEND_MODE_PLUS);
39// 将源像素的画刷效果设置到Canvas中
40OH_Drawing_CanvasAttachBrush(canvas, brush);
41// 创建圆心的点对象
42OH_Drawing_Point *point = OH_Drawing_PointCreate(600, 600);
43// 绘制圆(源像素)
44OH_Drawing_CanvasDrawCircle(canvas, point, 300);
45// 去除掉画布中的画刷
46OH_Drawing_CanvasDetachBrush(canvas);
47// 销毁各类对象
48OH_Drawing_RectDestroy(rect);
49OH_Drawing_BrushDestroy(brush);
50OH_Drawing_PointDestroy(point);
51```
52
53![zh-cn_image_0000002158744138](figures/zh-cn_image_0000002158744138.png)
54
55
56## 路径效果
57
58路径效果如虚线效果,只用于画笔。
59
60可使用OH_Drawing_CreateDashPathEffect()接口设置路径效果。接口接受3个参数,分别为:
61
62- 浮点数数组intervals:表示虚线或者点线的间隔。
63
64- 整数count:表示intervals数组中的元素数量。
65
66- 浮点数phase:表示在intervals数组中的偏移量,即从数组的哪个位置开始应用虚线或点线效果。
67
68此处以绘制矩形虚线路径效果为例,关键示例和效果示意图如下所示:
69
70```c++
71// 创建画笔
72OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
73// 设置画笔描边颜色
74OH_Drawing_PenSetColor(pen, 0xffff0000);
75// 设置画笔线宽
76OH_Drawing_PenSetWidth(pen, 10);
77// 表示10px的实线,5px的间隔,2px的实线,5px的间隔,以此循环
78float intervals[] = {10, 5, 2, 5};
79// 设置虚线路径效果
80OH_Drawing_PathEffect *pathEffect = OH_Drawing_CreateDashPathEffect(intervals, 4, 0.0);
81OH_Drawing_PenSetPathEffect(pen, pathEffect);
82// 在画布上设置画笔,请确保已获取得到画布对象
83OH_Drawing_CanvasAttachPen(canvas, pen);
84// 创建矩形
85OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900);
86// 绘制矩形
87OH_Drawing_CanvasDrawRect(canvas, rect);
88// 去除掉画布中的画笔
89OH_Drawing_CanvasDetachPen(canvas);
90// 销毁各类对象
91OH_Drawing_PenDestroy(pen);
92OH_Drawing_RectDestroy(rect);
93OH_Drawing_PathEffectDestroy(pathEffect);
94```
95
96| 不设置虚线路径效果的示意图 | 设置虚线效果的示意图 |
97| -------- | -------- |
98| ![zh-cn_image_0000002158584342](figures/zh-cn_image_0000002158584342.png) | ![zh-cn_image_0000002194110865](figures/zh-cn_image_0000002194110865.png) |
99
100
101## 着色器效果
102
103着色器效果基于画刷或画笔实现,可使用OH_Drawing_BrushSetShaderEffect()接口设置画刷的着色器效果,或者使用 OH_Drawing_PenSetShaderEffect接口设置画笔的着色器效果。当前支持不同的着色器效果,如线性渐变着色器效果、径向渐变着色器效果、扇形渐变着色器效果。
104
105着色器相关接口和具体参数的说明请见[drawing_shader_effect](../reference/apis-arkgraphics2d/drawing__shader__effect_8h.md)。
106
107
108### 线性渐变着色器效果
109
110可使用OH_Drawing_ShaderEffectCreateLinearGradient()接口创建想要设置的线性渐变着色器效果。接口接受6个参数,分别为开始点、结束点、颜色数组、相对位置数组、颜色数组的大小以及平铺模式。
111
112- 开始点和结束点用来确定渐变方向。
113
114- 颜色数组用于存储渐变使用到的颜色。
115
116- 相对位置数组则用于确定每种颜色在渐变中的相对位置,如果相对位置为空,颜色将会被均匀地分布在开始点和结束点之间。
117
118- 平铺模式用于确定如何在渐变区域之外继续渐变效果,平铺模式分为以下4类:
119  - CLAMP:当图像超出其原始边界时,复制边缘颜色。
120  - REPEAT:在水平和垂直方向上重复图像。
121  - MIRROR:在水平和垂直方向上重复图像,并在相邻的图像之间交替使用镜像图像。
122  - DECAL:只在原始域内绘制,在其他地方返回透明黑色。
123
124此处以绘制矩形并使用画刷设置线性渐变着色器效果为例,关键示例和效果示意图如下所示:
125
126```c++
127// 开始点
128OH_Drawing_Point *startPt = OH_Drawing_PointCreate(20, 20);
129// 结束点
130OH_Drawing_Point *endPt = OH_Drawing_PointCreate(900, 900);
131// 颜色数组
132uint32_t colors[] = {0xFFFFFF00, 0xFFFF0000, 0xFF0000FF};
133// 相对位置数组
134float pos[] = {0.0f, 0.5f, 1.0f};
135// 创建线性渐变着色器效果
136OH_Drawing_ShaderEffect *colorShaderEffect =
137    OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP);
138// 创建画刷对象
139OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
140// 基于画刷设置着色器效果
141OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect);
142// 在画布上设置画刷,请确保已获取得到画布对象
143OH_Drawing_CanvasAttachBrush(canvas, brush);
144OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 900, 900);
145 // 绘制矩形
146OH_Drawing_CanvasDrawRect(canvas, rect);
147// 去除掉画布中的画刷
148OH_Drawing_CanvasDetachBrush(canvas);
149// 销毁各类对象
150OH_Drawing_BrushDestroy(brush);
151OH_Drawing_RectDestroy(rect);
152OH_Drawing_ShaderEffectDestroy(colorShaderEffect);
153OH_Drawing_PointDestroy(startPt);
154OH_Drawing_PointDestroy(endPt);
155```
156
157此例绘制的具有线性渐变着色器效果的矩形如下所示:
158
159![zh-cn_image_0000002194110873](figures/zh-cn_image_0000002194110873.png)
160
161
162### 径向渐变着色器效果
163
164可使用OH_Drawing_ShaderEffectCreateRadialGradient()接口创建想要设置的径向渐变着色器效果。接口接受6个参数,分别为圆心坐标(centerPt)、半径(radius)、颜色数组(colors)、相对位置数组(pos)、颜色和位置的数量(size)以及平铺模式(OH_Drawing_TileMode)。
165
166其实现方式与线性渐变着色器类似,不同的是,径向渐变是由圆心开始向外径向渐变的。
167
168此处以绘制矩形并使用画刷设置径向渐变着色器效果为例,关键示例和效果示意图如下所示:
169
170```c++
171// 圆心坐标
172OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(500, 500);
173// 半径
174float radius = 600;
175// 颜色数组
176uint32_t gColors[] = {0xFFFF0000, 0xFF00FF00, 0xFF0000FF};
177// 相对位置数组
178float_t gPos[] = {0.0f, 0.25f, 0.75f};
179// 创建径向渐变着色器效果
180OH_Drawing_ShaderEffect *colorShaderEffect =
181    OH_Drawing_ShaderEffectCreateRadialGradient(centerPt, radius, gColors, gPos, 3, OH_Drawing_TileMode::REPEAT);
182// 创建画刷对象
183OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
184// 基于画刷设置着色器效果
185OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect);
186// 在画布上设置画刷,请确保已获取得到画布对象
187OH_Drawing_CanvasAttachBrush(canvas, brush);
188OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 900, 900);
189 // 绘制矩形
190OH_Drawing_CanvasDrawRect(canvas, rect);
191// 去除掉画布中的画刷
192OH_Drawing_CanvasDetachBrush(canvas);
193// 销毁各类对象
194OH_Drawing_BrushDestroy(brush);
195OH_Drawing_RectDestroy(rect);
196OH_Drawing_ShaderEffectDestroy(colorShaderEffect);
197OH_Drawing_PointDestroy(centerPt);
198```
199
200此例绘制的具有径向渐变着色器效果的矩形如下所示:
201
202![zh-cn_image_0000002158744130](figures/zh-cn_image_0000002158744130.png)
203
204
205### 扇形渐变着色器效果
206
207可使用OH_Drawing_ShaderEffectCreateSweepGradient()接口创建想要设置的扇形渐变着色器效果。接口接受5个参数,分别是中心点、颜色数组、相对位置数组、颜色和相对位置的数量以及平铺模式。
208
209其实现方式也与线性渐变着色器类似,不同的是,扇形渐变是在围绕中心点旋转的过程中渐变。
210
211此处以绘制矩形并使用画刷设置扇形渐变着色器效果为例,关键示例和效果示意图如下所示:
212
213```c++
214// 中心点
215OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(500, 500);
216// 颜色数组
217uint32_t colors[3] = {0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00};
218// 相对位置数组
219float pos[3] = {0.0f, 0.5f, 1.0f};
220// 创建扇形渐变着色器效果
221OH_Drawing_ShaderEffect* colorShaderEffect =
222    OH_Drawing_ShaderEffectCreateSweepGradient(centerPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP);
223// 创建画刷对象
224OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
225// 基于画刷设置着色器效果
226OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect);
227// 在画布上设置画刷,请确保已获取得到画布对象
228OH_Drawing_CanvasAttachBrush(canvas, brush);
229OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 900, 900);
230 // 绘制矩形
231OH_Drawing_CanvasDrawRect(canvas, rect);
232// 去除掉画布中的画刷
233OH_Drawing_CanvasDetachBrush(canvas);
234// 销毁各类对象
235OH_Drawing_BrushDestroy(brush);
236OH_Drawing_RectDestroy(rect);
237OH_Drawing_ShaderEffectDestroy(colorShaderEffect);
238OH_Drawing_PointDestroy(centerPt);
239```
240
241此例绘制的具有扇形渐变着色器效果的矩形如下所示:
242
243![zh-cn_image_0000002158584354](figures/zh-cn_image_0000002158584354.png)
244
245
246## 滤波器效果
247
248滤波器效果可基于画刷或画笔实现。可使用OH_Drawing_PenSetFilter()接口设置画笔的滤波器效果,或者使用OH_Drawing_BrushSetFilter()接口设置画刷的滤波器效果。当前支持不同的滤波器效果,比如图像滤波器、颜色滤波器、蒙版滤波器。
249
250滤波器相关接口和具体参数的说明请见[drawing_filter.h](../reference/apis-arkgraphics2d/drawing__filter_8h.md)。
251
252
253### 颜色滤波器效果
254
255颜色滤波器可基于画笔或画刷实现,颜色滤波器的相关接口和具体参数的说明请见[drawing_color_filter.h](../reference/apis-arkgraphics2d/drawing__color__filter_8h.md)。
256
257目前可实现多种颜色滤波器,包括如下:
258
259- 具有混合模式的颜色滤波器。
260
261- 具有5x4颜色矩阵的颜色滤波器。
262
263- 将SRGB的伽玛曲线应用到RGB颜色通道的颜色滤波器。
264
265- 将RGB颜色通道应用于SRGB的伽玛曲线的颜色滤波器。
266
267- 将其输入的亮度值乘以透明度通道, 并将红色、绿色和蓝色通道设置为零的颜色滤波器。
268
269- 由两个颜色滤波器组合而成的颜色滤波器。
270
271此处以具有5x4颜色矩阵的颜色滤波器为例。
272
273可使用OH_Drawing_ColorFilterCreateMatrix()接口创建具有5x4颜色矩阵的颜色滤波器。接口接受1个参数,表示为颜色矩阵,它是一个长度为20的浮点数数组。数组格式如下:
274
275[ a0, a1, a2, a3, a4 ]
276
277[ b0, b1, b2, b3, b4 ]
278
279[ c0, c1, c2, c3, c4 ]
280
281[ d0, d1, d2, d3, d4 ]
282
283对于每个原始的像素颜色色值(R, G, B, A),变换后的色值(R', G', B', A')计算公式为:
284
285R' = a0\*R + a1\*G + a2\*B + a3\*A + a4
286
287G' = b0\*R + b1\*G + b2\*B + b3\*A + b4
288
289B' = c0\*R + c1\*G + c2\*B + c3\*A + c4
290
291A' = d0\*R + d1\*G + d2\*B + d3\*A + d4
292
293此处以绘制矩形并使用画刷设置具有5x4颜色矩阵的颜色滤波器效果为例,关键示例和效果示意图如下所示:
294
295```c++
296// 创建画刷
297OH_Drawing_Brush *brush = OH_Drawing_BrushCreate();
298// 设置画刷抗锯齿
299OH_Drawing_BrushSetAntiAlias(brush, true);
300// 设置画刷填充颜色
301OH_Drawing_BrushSetColor(brush, 0xffff0000);
302// 设置颜色矩阵
303const float matrix[20] = {
304    1, 0, 0, 0, 0,
305    0, 1, 0, 0, 0,
306    0, 0, 0.5f, 0.5f, 0,
307    0, 0, 0.5f, 0.5f, 0
308};
309
310// 创建滤波器颜色
311OH_Drawing_ColorFilter* colorFilter = OH_Drawing_ColorFilterCreateMatrix(matrix);
312// 创建一个滤波器对象
313OH_Drawing_Filter *filter = OH_Drawing_FilterCreate();
314// 为滤波器对象设置颜色滤波器
315OH_Drawing_FilterSetColorFilter(filter, colorFilter);
316// 设置画刷的滤波器效果
317OH_Drawing_BrushSetFilter(brush, filter);
318// 在画布上设置画刷,请确保已获取得到画布对象
319OH_Drawing_CanvasAttachBrush(canvas, brush);
320// 创建矩形
321OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900);
322// 绘制矩形
323OH_Drawing_CanvasDrawRect(canvas, rect);
324// 去除掉画布中的画刷
325OH_Drawing_CanvasDetachBrush(canvas);
326// 销毁各类对象
327OH_Drawing_BrushDestroy(brush);
328OH_Drawing_ColorFilterDestroy(colorFilter);
329OH_Drawing_RectDestroy(rect);
330OH_Drawing_FilterDestroy(filter);
331```
332
333| 不设置颜色滤波器效果的示意图 | 设置5x4颜色矩阵的颜色滤波器效果的示意图 |
334| -------- | -------- |
335| ![zh-cn_image_0000002194110869](figures/zh-cn_image_0000002194110869.png) | ![zh-cn_image_0000002194025241](figures/zh-cn_image_0000002194025241.png) |
336
337
338### 图像滤波器效果
339
340图像滤波器可基于画笔或画刷来实现,图像滤波器的相关接口和具体参数的说明请见[drawing_image_filter.h](../reference/apis-arkgraphics2d/drawing__image__filter_8h.md)。
341
342目前只支持两种图像滤波器:
343
344- 基于颜色滤波器的图像滤波器。
345  可通过OH_Drawing_ImageFilterCreateFromColorFilter()接口实现,接口接受2个参数,颜色滤波器colorFilter和图像滤波器input,即把颜色滤波器的效果叠加到图像滤波器input上,input可为空,input为空则只添加颜色滤波器效果。
346
347- 具有模糊效果的图像滤波器。
348  可通过OH_Drawing_ImageFilterCreateBlur()接口实现,接口接受4个参数,分别为X轴上的模糊标准差、Y轴上的模糊标准差、平铺模式和图像滤波器(input)。
349
350  最终效果即为在输入的图像滤波器(input)的基础上进行模糊化处理,即滤波器效果可叠加,input可为空,input为空则只添加模糊效果。
351
352此处以绘制矩形并使用画笔添加模糊效果的图像滤波器效果为例,关键示例和效果示意图如下所示:
353
354```c++
355// 创建画笔
356OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
357// 设置画笔抗锯齿
358OH_Drawing_PenSetAntiAlias(pen, true);
359// 设置画笔描边颜色
360OH_Drawing_PenSetColor(pen, 0xffff0000);
361// 设置画笔线宽
362OH_Drawing_PenSetWidth(pen, 20);
363// 创建图像滤波器实现模糊效果
364OH_Drawing_ImageFilter *imageFilter =
365    OH_Drawing_ImageFilterCreateBlur(20.0f, 20.0f, OH_Drawing_TileMode::CLAMP, nullptr);
366// 创建一个滤波器对象
367OH_Drawing_Filter *filter = OH_Drawing_FilterCreate();
368// 为滤波器对象设置图像滤波器
369OH_Drawing_FilterSetImageFilter(filter, imageFilter);
370// 设置画笔的滤波器效果
371OH_Drawing_PenSetFilter(pen, filter);
372// 在画布上设置画笔,请确保已获取得到画布对象
373OH_Drawing_CanvasAttachPen(canvas, pen);
374// 创建矩形
375OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900);
376// 绘制矩形
377OH_Drawing_CanvasDrawRect(canvas, rect);
378// 去除掉画布中的画笔
379OH_Drawing_CanvasDetachPen(canvas);
380// 销毁各类对象
381OH_Drawing_PenDestroy(pen);
382OH_Drawing_ImageFilterDestroy(imageFilter);
383OH_Drawing_RectDestroy(rect);
384OH_Drawing_FilterDestroy(filter);
385```
386
387| 不设置图像滤波器效果的示意图 | 设置图像滤波器效果的示意图 |
388| -------- | -------- |
389| ![zh-cn_image_0000002194025225](figures/zh-cn_image_0000002194025225.png) | ![zh-cn_image_0000002194025245](figures/zh-cn_image_0000002194025245.png) |
390
391
392### 蒙版滤波器效果
393
394蒙版滤波器的模糊效果仅对透明度和形状边缘进行模糊处理,相对于图像滤波器的模糊效果来说计算成本更低。
395
396蒙版滤波器可基于画笔或画刷实现,蒙版滤波器的相关接口和具体参数的说明请见[drawing_mask_filter.h](../reference/apis-arkgraphics2d/drawing__mask__filter_8h.md)。
397
398可使用H_Drawing_MaskFilterCreateBlur()接口创建想要设置具有模糊效果的蒙版滤波器。接口接受3个参数,分别为:
399
400- blurType:用于指定要应用的模糊类型,详细分类请参考[BlurType](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blurtype12)。
401
402- sigma:用于指定要应用的高斯模糊的标准差,标准差必须大于0。
403
404- respectCTM:指定模糊的标准差是否会被CTM(coordinate transformation matrix,坐标变换矩阵)修改,默认为true,表示会被对应修改。
405
406此处以绘制矩形并使用画笔设置蒙版滤波器效果为例,关键示例和效果示意图如下所示:
407
408```c++
409// 创建画笔
410OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
411// 设置画笔抗锯齿
412OH_Drawing_PenSetAntiAlias(pen, true);
413// 设置画笔描边颜色
414OH_Drawing_PenSetColor(pen, 0xffff0000);
415// 设置画笔线宽
416OH_Drawing_PenSetWidth(pen, 20);
417// 创建蒙版滤波器
418OH_Drawing_MaskFilter *maskFilter = OH_Drawing_MaskFilterCreateBlur(OH_Drawing_BlurType::NORMAL, 20, true);
419// 创建一个滤波器对象
420OH_Drawing_Filter *filter = OH_Drawing_FilterCreate();
421// 为滤波器对象设置蒙版滤波器
422OH_Drawing_FilterSetMaskFilter(filter, maskFilter);
423// 设置画笔的滤波器效果
424OH_Drawing_PenSetFilter(pen, filter);
425// 在画布上设置画笔,请确保已获取得到画布对象
426OH_Drawing_CanvasAttachPen(canvas, pen);
427// 创建矩形
428OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900);
429// 绘制矩形
430OH_Drawing_CanvasDrawRect(canvas, rect);
431// 去除掉画布中的画笔
432OH_Drawing_CanvasDetachPen(canvas);
433// 销毁各类对象
434OH_Drawing_PenDestroy(pen);
435OH_Drawing_MaskFilterDestroy(maskFilter);
436OH_Drawing_RectDestroy(rect);
437OH_Drawing_FilterDestroy(filter);
438```
439
440| 不设置蒙版滤波器效果的示意图 | 设置蒙版滤波器效果的示意图 |
441| -------- | -------- |
442| ![zh-cn_image_0000002194110877](figures/zh-cn_image_0000002194110877.png) | ![zh-cn_image_0000002158744126](figures/zh-cn_image_0000002158744126.png) |
443
444<!--RP1-->
445## 相关实例
446
447针对Drawing(C/C++)的开发,有以下相关实例可供参考:
448
449- [NDKGraphicsDraw (API14)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Drawing/NDKGraphicsDraw)
450<!--RP1End-->