• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 复杂绘制效果(ArkTS)
2
3<!--Kit: ArkGraphics 2D-->
4<!--Subsystem: Graphics-->
5<!--Owner: @hangmengxin-->
6<!--Designer: @wangyanglan-->
7<!--Tester: @nobuggers-->
8<!--Adviser: @ge-yafang-->
9
10除了基础填充颜色、描边颜色和一些样式设置的绘制效果外,还支持通过画刷和画笔实现更多复杂的绘制效果。比如:
11
12
13- 混合模式。
14
15- 路径效果,如虚线效果。
16
17- 着色器效果,如线性渐变、径向渐变等。
18
19- 滤波效果,如模糊效果等。
20
21
22## 混合模式
23
24混合模式可以用于画笔或画刷,它定义了如何将源像素(要绘制的内容)与目标像素(已存在于画布上的内容)进行组合。
25
26可以使用setBlendMode()接口将混合模式应用于画刷或画笔中,该接口需要接受一个参数BlendMode,即混合模式的类型,具体可参考[BlendMode](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-e.md#blendmode)。
27
28此处以使用画刷设置叠加混合模式为例(为了防止混合模式的效果被背景色干扰,示例中的canvas并未设置背景色,使用的是默认的黑色背景),关键示例和效果示意图如下所示:
29
30```ts
31// 创建画刷
32let brush = new drawing.Brush();
33// 设置目标像素颜色,即矩形的颜色
34brush.setColor(0xFF, 0xFF,  0x00, 0x00);
35// 将目标像素的画刷效果设置到Canvas中
36canvas.attachBrush(brush);
37// 创建矩形对象
38let rect: common2D.Rect = { left: 100, top: 100, right: 600, bottom: 600 };
39// 绘制矩形(目标像素)
40canvas.drawRect(rect);
41// 设置源像素颜色,即圆形的颜色
42brush.setColor(0xFF, 0x00,  0x00, 0xFF);
43// 设置混合模式为叠加模式
44brush.setBlendMode(drawing.BlendMode.PLUS);
45// 将源像素的画刷效果设置到Canvas中
46canvas.attachBrush(brush);
47// 绘制圆(源像素)
48canvas.drawCircle(600, 600, 300);
49// 去除填充效果
50canvas.detachBrush();
51```
52
53![zh-cn_image_0000002194025221](figures/zh-cn_image_0000002194025221.png)
54
55
56## 路径效果
57
58路径效果如虚线效果,只用于画笔。
59
60可使用createDashPathEffect()接口设置路径效果。接口接受2个参数,分别为:
61
62- 浮点数数组intervals:表示虚线或者点线的间隔。
63
64- 浮点数phase:表示在intervals数组中的偏移量,即从数组的哪个位置开始应用虚线或点线效果。
65
66此处以绘制矩形虚线路径效果为例,关键示例和效果示意图如下所示:
67
68```ts
69// 创建画笔
70let pen = new drawing.Pen();
71// 设置线宽
72pen.setStrokeWidth(10.0);
73// 设置颜色
74pen.setColor(0xFF, 0xFF, 0x00, 0x00);
75// 表示10px的实线,5px的间隔,2px的实线,5px的间隔,以此循环
76let intervals = [10, 5, 2, 5];
77// 设置虚线路径效果
78let effect = drawing.PathEffect.createDashPathEffect(intervals, 0);
79pen.setPathEffect(effect);
80// 设置画笔描边效果
81canvas.attachPen(pen);
82// 创建矩形
83let rect: common2D.Rect = { left: 200, top: 200, right: 1000, bottom: 700 };
84// 绘制矩形
85canvas.drawRect(rect);
86// 去除描边效果
87canvas.detachPen();
88```
89
90| 原始图 | 设置虚线效果后的效果图 |
91| -------- | -------- |
92| ![Screenshot_20241130160231398](figures/Screenshot_20241130160231398.jpg) | ![Screenshot_20241130160433593](figures/Screenshot_20241130160433593.jpg) |
93
94
95## 着色器效果
96
97着色器效果基于画刷或画笔实现,可使用setShaderEffect()接口设置画刷或画笔的着色器效果。当前支持不同的着色器效果,如线性渐变着色器效果、径向渐变着色器效果、扇形渐变着色器效果。
98
99
100着色器相关接口和具体参数的说明请见[ShaderEffect](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-ShaderEffect.md)。
101
102
103### 线性渐变着色器效果
104
105可使用createLinearGradient()接口创建想要设置的线性渐变着色器效果。接口接受6个参数,分别是开始点、结束点、颜色数组、平铺模式、相对位置数组以及矩阵对象。
106
107- 开始点和结束点用来确定渐变方向。
108
109- 颜色数组用于存储渐变使用到的颜色。
110
111- 相对位置数组则用于确定每种颜色在渐变中的相对位置,如果相对位置为空,颜色将会被均匀地分布在开始点和结束点之间。
112
113- 矩阵对象,用于对着色器做矩阵变换,默认为null,表示单位矩阵。
114
115- 平铺模式用于确定如何在渐变区域之外继续渐变效果,平铺模式分为以下4类:
116  - CLAMP:当图像超出其原始边界时,复制边缘颜色。
117  - REPEAT:在水平和垂直方向上重复图像。
118  - MIRROR:在水平和垂直方向上重复图像,并在相邻的图像之间交替使用镜像图像。
119  - DECAL:只在原始域内绘制,在其他地方返回透明黑色。
120
121此处以绘制矩形并使用画刷设置线性渐变着色器效果为例,关键示例和效果示意图如下所示:
122
123```ts
124let startPt: common2D.Point = { x: 100, y: 100 };
125let endPt: common2D.Point = { x: 900, y: 900 };
126let colors = [0xFFFFFF00, 0xFFFF0000, 0xFF0000FF];
127// 创建线性渐变着色器
128let shaderEffect = drawing.ShaderEffect.createLinearGradient(startPt, endPt, colors, drawing.TileMode.CLAMP);
129// 创建画刷
130let brush = new drawing.Brush();
131// 设置线性着色器
132brush.setShaderEffect(shaderEffect);
133// 设置画刷填充效果
134canvas.attachBrush(brush);
135let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
136// 绘制矩形
137canvas.drawRect(rect);
138// 去除填充效果
139canvas.detachBrush();
140```
141
142![zh-cn_image_0000002158744106](figures/zh-cn_image_0000002158744106.png)
143
144
145### 径向渐变着色器效果
146
147可使用createRadialGradient()接口创建想要设置的径向渐变着色器效果。接口接受6个参数,分别是圆心坐标(centerPt)、半径(radius)、颜色数组(colors)、平铺模式(TileMode)、相对位置数组(pos)以及矩阵对象(matrix)。
148
149其实现方式与线性渐变着色器类似,不同的是,径向渐变是由圆心开始向外径向渐变的。
150
151此处以绘制矩形并使用画刷设置径向渐变着色器效果为例,关键示例和效果示意图如下所示:
152
153```ts
154let centerPt: common2D.Point = { x: 500, y: 500 };
155let colors = [0xFFFF0000, 0xFF00FF00, 0xFF0000FF];
156// 创建径向渐变着色器
157let shaderEffect = drawing.ShaderEffect.createRadialGradient(centerPt, 600, colors, drawing.TileMode.CLAMP);
158// 创建画刷
159let brush = new drawing.Brush();
160// 设置径向渐变着色器
161brush.setShaderEffect(shaderEffect);
162// 设置画刷填充效果
163canvas.attachBrush(brush);
164let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
165// 绘制矩形
166canvas.drawRect(rect);
167// 去除填充效果
168canvas.detachBrush();
169```
170
171![Screenshot_20241130164939281](figures/Screenshot_20241130164939281.jpg)
172
173
174### 扇形渐变着色器效果
175
176可使用createSweepGradient()接口创建想要设置的扇形渐变着色器效果。接口接受7个参数,分别是圆心坐标(centerPt)、颜色数组(colors)、平铺模式(TileMode)、扇形渐变的起始角度(startAngle)、扇形渐变的结束角度(endAngle)、相对位置数组(pos)以及矩阵对象(matrix)。
177
178其实现方式也与线性渐变着色器类似,不同的是,扇形渐变是在围绕中心点旋转的过程中渐变。
179
180此处以绘制矩形并使用画刷设置扇形渐变着色器效果为例,关键示例和效果示意图如下所示:
181
182```ts
183let centerPt: common2D.Point = { x: 500, y: 500 };
184let colors = [0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00];
185// 创建扇形渐变着色器
186let shaderEffect = drawing.ShaderEffect.createSweepGradient(centerPt, colors, drawing.TileMode.CLAMP, 0, 360);
187// 创建画刷
188let brush = new drawing.Brush();
189// 设置扇形渐变着色器
190brush.setShaderEffect(shaderEffect);
191// 设置画刷填充效果
192canvas.attachBrush(brush);
193let rect: common2D.Rect = { left: 100, top: 100, right: 900, bottom: 900 };
194// 绘制矩形
195canvas.drawRect(rect);
196// 去除填充效果
197canvas.detachBrush();
198```
199
200![Screenshot_20241130165741720](figures/Screenshot_20241130165741720.jpg)
201
202
203## 滤波器效果
204
205滤波器效果可基于画刷或画笔实现。当前支持不同的滤波器效果,比如图像滤波器、颜色滤波器、蒙版滤波器。
206
207滤波器相关接口和具体参数的说明请见[ImageFilter](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-ImageFilter.md)。
208
209
210### 颜色滤波器效果
211
212颜色滤波器可基于画笔或画刷实现,颜色滤波器的相关接口和具体参数的说明请见[ColorFilter](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-ColorFilter.md)。
213
214目前可实现多种颜色滤波器,包括如下:
215
216- 具有混合模式的颜色滤波器。
217
218- 具有5x4颜色矩阵的颜色滤波器。
219
220- 将SRGB的伽玛曲线应用到RGB颜色通道的颜色滤波器。
221
222- 将RGB颜色通道应用于SRGB的伽玛曲线的颜色滤波器。
223
224- 将其输入的亮度值乘以透明度通道, 并将红色、绿色和蓝色通道设置为零的颜色滤波器。
225
226- 由两个颜色滤波器组合而成的颜色滤波器。
227
228此处以具有5x4颜色矩阵的颜色滤波器为例。
229
230可使用createMatrixColorFilter()接口创建具有5x4颜色矩阵的颜色滤波器。接口接受1个参数,表示为颜色矩阵,它是一个长度为20的浮点数数组。数组格式如下:
231
232[ a0, a1, a2, a3, a4 ]
233
234[ b0, b1, b2, b3, b4 ]
235
236[ c0, c1, c2, c3, c4 ]
237
238[ d0, d1, d2, d3, d4 ]
239
240对于每个原始的像素颜色色值(R, G, B, A),变换后的色值(R', G', B', A')计算公式为:
241
242R' = a0\*R + a1\*G + a2\*B + a3\*A + a4
243
244G' = b0\*R + b1\*G + b2\*B + b3\*A + b4
245
246B' = c0\*R + c1\*G + c2\*B + c3\*A + c4
247
248A' = d0\*R + d1\*G + d2\*B + d3\*A + d4
249
250此处以绘制矩形并使用画刷设置具有5x4颜色矩阵的颜色滤波器效果为例,关键示例和效果示意图如下所示:
251
252```ts
253// 创建画刷
254let brush = new drawing.Brush();
255// 设置颜色
256brush.setColor(0xFF, 0xFF, 0x00, 0x00);
257// 设置颜色矩阵
258let matrix: Array<number> = [
259  1, 0, 0, 0, 0,
260  0, 1, 0, 0, 0,
261  0, 0, 0.5, 0.5, 0,
262  0, 0, 0.5, 0.5, 0
263];
264// 创建5x4颜色矩阵的颜色滤波器
265let filter = drawing.ColorFilter.createMatrixColorFilter(matrix);
266// 设置颜色滤波器
267brush.setColorFilter(filter);
268// 设置画刷填充效果
269canvas.attachBrush(brush);
270let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
271// 绘制矩形
272canvas.drawRect(rect);
273// 去除填充效果
274canvas.detachBrush();
275```
276
277| 原始图 | 设置5x4颜色矩阵的颜色滤波器后的效果图 |
278| -------- | -------- |
279| ![Screenshot_20241130173415925](figures/Screenshot_20241130173415925.jpg) | ![Screenshot_20241130173354704](figures/Screenshot_20241130173354704.jpg) |
280
281
282### 图像滤波器效果
283
284图像滤波器可基于画笔或画刷来实现,图像滤波器的相关接口和具体参数的说明请见[ImageFilter](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-ImageFilter.md)。
285
286目前只支持两种图像滤波器:
287
288- 基于颜色滤波器的图像滤波器。
289  可通过createFromColorFilter()接口实现,接口接受2个参数,颜色滤波器colorFilter和图像滤波器imageFilter,即把颜色滤波器的效果叠加到图像滤波器imageFilter上,imageFilter可为空,imageFilter为空则只添加颜色滤波器效果。
290
291- 具有模糊效果的图像滤波器。
292  可通过createBlurImageFilter()接口实现,接口接受4个参数,sigmaX,sigmaY,cTileMode和imageFilter。sigmaX和sigmaY是模糊的标准差,cTileMode是平铺模式,imageFilter是输入的图像滤波器。
293
294  最终效果即为在输入的图像滤波器imageFilter的基础上进行模糊化处理,即滤波器效果可叠加,imageFilter可为空,imageFilter为空则只添加模糊效果。
295
296此处以绘制矩形并使用画笔添加模糊效果的图像滤波器效果为例,关键示例和效果示意图如下所示:
297
298```ts
299// 设置画笔
300let pen = new drawing.Pen();
301// 设置线宽
302pen.setStrokeWidth(10.0);
303// 设置颜色
304pen.setColor(0xFF, 0xFF, 0x00, 0x00);
305// 创建模糊效果图像滤波器
306let filter = drawing.ImageFilter.createBlurImageFilter(20, 20, drawing.TileMode.CLAMP);
307// 设置图像滤波器
308pen.setImageFilter(filter);
309// 设置画笔描边效果
310canvas.attachPen(pen);
311let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
312// 绘制矩形
313canvas.drawRect(rect);
314// 去除描边效果
315canvas.detachPen();
316```
317
318| 原始图 | 设置模糊效果后的效果图 |
319| -------- | -------- |
320| ![Screenshot_20241130170911500](figures/Screenshot_20241130170911500.jpg) | ![Screenshot_20241130170826458](figures/Screenshot_20241130170826458.jpg) |
321
322
323### 蒙版滤波器效果
324
325蒙版滤波器的模糊效果仅对透明度和形状边缘进行模糊处理,相对于图像滤波器的模糊效果来说计算成本更低。
326
327蒙版滤波器可基于画笔或画刷实现,蒙版滤波器的相关接口和具体参数的说明请见[MaskFilter](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-MaskFilter.md)。
328
329可使用createBlurMaskFilter()接口创建想要设置具有模糊效果的蒙版滤波器。接口接受2个参数,分别为:
330
331- blurType:用于指定要应用的模糊类型,详细分类请参考[BlurType](../reference/apis-arkgraphics2d/arkts-apis-graphics-drawing-e.md#blurtype12)。
332
333- sigma:用于指定要应用的高斯模糊的标准差,标准差必须大于0。
334
335此处以绘制矩形并使用画笔设置蒙版滤波器效果为例,关键示例和效果示意图如下所示:
336
337```ts
338// 创建画笔
339let pen = new drawing.Pen();
340// 设置线宽
341pen.setStrokeWidth(10.0);
342// 设置颜色
343pen.setColor(0xFF, 0xFF, 0x00, 0x00);
344// 创建模糊效果的蒙版滤波器
345let filter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, 20);
346// 设置模糊效果
347pen.setMaskFilter(filter);
348// 设置画笔描边效果
349canvas.attachPen(pen);
350let rect: common2D.Rect = { left: 300, top: 300, right: 900, bottom: 900 };
351// 绘制矩形
352canvas.drawRect(rect);
353// 去除描边效果
354canvas.detachPen();
355```
356
357| 原始图 | 设置模糊效果后的效果图 |
358| -------- | -------- |
359| ![Screenshot_20241130170911500](figures/Screenshot_20241130170911500.jpg) | ![Screenshot_20241130170826458](figures/Screenshot_20241130170826458.jpg) |
360
361<!--RP1-->
362## 相关实例
363
364针对Drawing(ArkTS)的开发,有以下相关实例可供参考:
365
366- [ArkTSGraphicsDraw (API14)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Drawing/ArkTSGraphicsDraw)
367<!--RP1End-->