1# Complex Drawing Effects (C/C++) 2 3 4In addition to the basic fill color, stroke color, and some style settings, you can also use penes and penes to implement more complex drawing effects. For example, 5 6 7- Blend mode. 8 9- Path effect, such as the dotted line effect. 10 11- Shader effect, such as linear gradient and radial gradient. 12 13- Filtering effect, such as the blur effect. 14 15 16## Blend Mode 17 18The blend mode can be used for penes or penes. It defines how to combine the source pixel (content to be drawn) with the target pixel (content that already exists on the canvas). 19 20You can use the OH_Drawing_penSetBlendMode() interface to apply the blending mode to the pen, and use the OH_Drawing_PenSetBlendMode interface to apply the blending mode to the pen. Both APIs need to accept the OH_Drawing_BlendMode parameter, that is, the blending mode type. For details, see [BlendMode](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blendmode). 21 22The following uses the brush as an example to describe how to set the blending mode. (To prevent the blending mode from being interfered by the background color, the background color is not set for the canvas in the example, and the default black background is used.) The following figure shows the key example and effect. 23 24```c++ 25// Create a brush object. 26OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 27// Set the target pixel color. 28OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); 29// Set the brush effect of the target pixel in Canvas. 30OH_Drawing_CanvasAttachBrush(canvas, brush); 31// Create a rectangle object. 32OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 600, 600); 33// Draw a rectangle (target pixel). 34OH_Drawing_CanvasDrawRect(canvas, rect); 35// Set the source pixel color. 36OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0xFF)); 37// Set the blending mode to overlay. 38OH_Drawing_BrushSetBlendMode(brush, OH_Drawing_BlendMode::BLEND_MODE_PLUS); 39// Set the brush effect of the source pixel to Canvas. 40OH_Drawing_CanvasAttachBrush(canvas, brush); 41// Create a point object for the center of a circle. 42OH_Drawing_Point *point = OH_Drawing_PointCreate(600, 600); 43// Draw a circle (source pixel). 44OH_Drawing_CanvasDrawCircle(canvas, point, 300); 45// Remove the brush from the canvas. 46OH_Drawing_CanvasDetachBrush(canvas); 47// Destroy various objects. 48OH_Drawing_RectDestroy(rect); 49OH_Drawing_BrushDestroy(brush); 50OH_Drawing_PointDestroy(point); 51``` 52 53 54 55 56## Path Effects 57 58The path effect is similar to the dotted line effect, which is used only for penes. 59 60You can set the path effect by calling OH_Drawing_CreateDashPathEffect(). The interface accepts the following parameters: 61 62- Floating-point array intervals: indicates the interval between dotted lines or dots. 63 64- Integer count: indicates the number of elements in the intervals array. 65 66- Floating-point number phase: indicates the offset in the intervals array, that is, the position from which the dotted line or dot line effect is applied. 67 68The following uses the drawing of a rectangular dotted line as an example. The following figure shows the key example and effect. 69 70```c++ 71// Create a pen. 72OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); 73// Set the stroke color. 74OH_Drawing_PenSetColor(pen, 0xffff0000); 75// Set the line width of the pen. 76OH_Drawing_PenSetWidth(pen, 10); 77// 10px solid line, 5px interval, 2px solid line, 5px interval, and so on 78float intervals[] = {10, 5, 2, 5}; 79// Set the dotted line path effect. 80OH_Drawing_PathEffect *pathEffect = OH_Drawing_CreateDashPathEffect(intervals, 4, 0.0); 81OH_Drawing_PenSetPathEffect(pen, pathEffect); 82// Set the pen on the canvas. Ensure that the canvas object has been obtained. 83OH_Drawing_CanvasAttachPen(canvas, pen); 84// Create a rectangle. 85OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900); 86// Draw a rectangle. 87OH_Drawing_CanvasDrawRect(canvas, rect); 88// Remove the pen from the canvas. 89OH_Drawing_CanvasDetachPen(canvas); 90// Destroy various objects. 91OH_Drawing_PenDestroy(pen); 92OH_Drawing_RectDestroy(rect); 93OH_Drawing_PathEffectDestroy(pathEffect); 94``` 95 96| Effect of not setting a dotted line path| Setting the dotted line effect| 97| -------- | -------- | 98|  |  | 99 100 101## Shader Effects 102 103The shader effect is implemented based on the pen or pen. You can call OH_Drawing_penSetShaderEffect() to set the shader effect of the pen, you can also call the OH_Drawing_PenSetShaderEffect API to set the shader effect of the pen. Currently, different shader effects are supported, such as linear gradient shader, radial gradient shader, and sector gradient shader. 104 105For details about shader APIs and parameters, see [drawing_shader_effect](../reference/apis-arkgraphics2d/drawing__shader__effect_8h.md). 106 107 108### Linear Gradient Shader Effects 109 110You can call OH_Drawing_ShaderEffectCreateLinearGradient() to create the linear gradient shader effect to be set. The interface accepts six parameters: start point, end point, color array, relative position array, color array size, and tile mode. 111 112- The start point and the end point are used to determine a gradient direction. 113 114- The color array is used to store colors used for gradient. 115 116- The relative position array is used to determine a relative position of each color in the gradient. If the relative position is empty, the colors are evenly distributed between the start point and the end point. 117 118- The tile mode is used to determine how to continue the gradient effect outside the gradient area. The tile mode is classified into the following four types: 119 - CLAMP: When the image exceeds its original boundary, the edge color is copied. 120 - REPEAT: repeats the image in the horizontal and vertical directions. 121 - MIRROR: Images are repeated in the horizontal and vertical directions, and mirror images are used alternately between adjacent images. 122 - DECAL: Draws only in the original domain and returns the transparent black color in other places. 123 124The following describes how to draw a rectangle and use the brush to set the linear gradient shader effect. The following figure shows the key example and effect. 125 126```c++ 127// Start point 128OH_Drawing_Point *startPt = OH_Drawing_PointCreate(20, 20); 129To 130OH_Drawing_Point *endPt = OH_Drawing_PointCreate(900, 900); 131Color array. 132uint32_t colors[] = {0xFFFFFF00, 0xFFFF0000, 0xFF0000FF}; 133// Relative position array 134float pos[] = {0.0f, 0.5f, 1.0f}; 135// Create a linear gradient shader effect. 136OH_Drawing_ShaderEffect *colorShaderEffect = 137 OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); 138// Create a brush object. 139OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 140// Set the shader effect based on the brush. 141OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); 142// Set the brush on the canvas. Ensure that the canvas object has been obtained. 143OH_Drawing_CanvasAttachBrush(canvas, brush); 144OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 900, 900); 145 // Draw a rectangle. 146OH_Drawing_CanvasDrawRect(canvas, rect); 147// Remove the brush from the canvas. 148OH_Drawing_CanvasDetachBrush(canvas); 149// Destroy various objects. 150OH_Drawing_BrushDestroy(brush); 151OH_Drawing_RectDestroy(rect); 152OH_Drawing_ShaderEffectDestroy(colorShaderEffect); 153OH_Drawing_PointDestroy(startPt); 154OH_Drawing_PointDestroy(endPt); 155``` 156 157The rectangle with the linear gradient shader effect drawn in this example is as follows: 158 159 160 161 162### Radial Gradient Shader Effects 163 164You can call the OH_Drawing_ShaderEffectCreateRadialGradient() API to create a radial gradient shader effect. The interface accepts six parameters: centerPt, radius, colors, pos, size, and OH_Drawing_TileMode. 165 166An implementation of the radial gradient shader is similar to that of the linear gradient shader, and a difference is that the radial gradient is radially changed outward from the center of the circle. 167 168The following describes how to draw a rectangle and use the brush to set the radial gradient shader effect. The following figure shows the key example and effect. 169 170```c++ 171// Coordinates of the circle center 172OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(500, 500); 173radius 174float radius = 600; 175Color array. 176uint32_t gColors[] = {0xFFFF0000, 0xFF00FF00, 0xFF0000FF}; 177// Relative position array 178float_t gPos[] = {0.0f, 0.25f, 0.75f}; 179// Create a radial gradient shader effect. 180OH_Drawing_ShaderEffect *colorShaderEffect = 181 OH_Drawing_ShaderEffectCreateRadialGradient(centerPt, radius, gColors, gPos, 3, OH_Drawing_TileMode::REPEAT); 182// Create a brush object. 183OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 184// Set the shader effect based on the brush. 185OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); 186// Set the brush on the canvas. Ensure that the canvas object has been obtained. 187OH_Drawing_CanvasAttachBrush(canvas, brush); 188OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 900, 900); 189 // Draw a rectangle. 190OH_Drawing_CanvasDrawRect(canvas, rect); 191// Remove the brush from the canvas. 192OH_Drawing_CanvasDetachBrush(canvas); 193// Destroy various objects. 194OH_Drawing_BrushDestroy(brush); 195OH_Drawing_RectDestroy(rect); 196OH_Drawing_ShaderEffectDestroy(colorShaderEffect); 197OH_Drawing_PointDestroy(centerPt); 198``` 199 200In this example, the rectangle with the radial gradient shader effect is as follows: 201 202 203 204 205### Sector Gradient Shader Effects 206 207You can call the OH_Drawing_ShaderEffectCreateSweepGradient() API to create the desired sector gradient shader effect. The interface accepts five parameters: center point, color array, relative position array, number of colors and relative positions, and tile mode. 208 209The implementation is similar to that of the linear gradient shader. The difference is that the sector gradient changes in the process of rotating around the center point. 210 211The following describes how to draw a rectangle and use the brush to set the sector gradient shader effect. The following figure shows the key example and effect. 212 213```c++ 214Center 215OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(500, 500); 216Color array. 217uint32_t colors[3] = {0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00}; 218// Relative position array 219float pos[3] = {0.0f, 0.5f, 1.0f}; 220// Create a sector gradient shader effect. 221OH_Drawing_ShaderEffect* colorShaderEffect = 222 OH_Drawing_ShaderEffectCreateSweepGradient(centerPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); 223// Create a brush object. 224OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 225// Set the shader effect based on the brush. 226OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); 227// Set the brush on the canvas. Ensure that the canvas object has been obtained. 228OH_Drawing_CanvasAttachBrush(canvas, brush); 229OH_Drawing_Rect *rect = OH_Drawing_RectCreate(100, 100, 900, 900); 230 // Draw a rectangle. 231OH_Drawing_CanvasDrawRect(canvas, rect); 232// Remove the brush from the canvas. 233OH_Drawing_CanvasDetachBrush(canvas); 234// Destroy various objects. 235OH_Drawing_BrushDestroy(brush); 236OH_Drawing_RectDestroy(rect); 237OH_Drawing_ShaderEffectDestroy(colorShaderEffect); 238OH_Drawing_PointDestroy(centerPt); 239``` 240 241In this example, the rectangle with the sector gradient shader effect is as follows: 242 243 244 245 246## Filter Effects 247 248The filter effect may be implemented based on a pen or a pen. You can call the OH_Drawing_PenSetFilter() interface to set the filter effect of the pen or call the OH_Drawing_penSetFilter() interface to set the filter effect of the pen. Currently, different filter effects are supported, such as the image filter, color filter, and mask filter. 249 250For details about the filter APIs and parameters, see [drawing_filter.h](../reference/apis-arkgraphics2d/drawing__filter_8h.md). 251 252 253### Color Filter Effects 254 255The color filter can be implemented based on the pen or pen. For details about the color filter APIs and parameters, see [drawing_color_filter.h](../reference/apis-arkgraphics2d/drawing__color__filter_8h.md). 256 257Currently, multiple color filters can be implemented, including: 258 259- Creates an **OH_Drawing_ColorFilter** object with a given blend mode. 260 261- Creates an **OH_Drawing_ColorFilter** object with a given 5x4 color matrix. 262 263- Apply the gamma curve of SRGB to the color filter of the RGB color channel. 264 265- A color filter that applies the RGB color channel to the gamma curve of SRGB. 266 267- A color filter that multiplies its input luminance value by the alpha channel and sets the red, green, and blue channels to zero. 268 269- A color filter that consists of two color filters. 270 271Here, a color filter with a 5x4 color matrix is used as an example. 272 273You can create a color filter with a 5x4 color matrix by calling OH_Drawing_ColorFilterCreateMatrix(). The interface takes one parameter, which is represented as a color matrix. It is an array of floating point numbers with a length of 20. The array format is as follows: 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 283For each original pixel color value (R, G, B, A), a transformed color value (R', G', B', A') is calculated as follows: 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 293The following describes how to draw a rectangle and use the brush to set the color filter effect with a 5 x 4 color matrix. The following figure shows the key example and effect. 294 295```c++ 296// Create a brush. 297OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); 298// Set the brush anti-aliasing. 299OH_Drawing_BrushSetAntiAlias(brush, true); 300// Set the brush fill color. 301OH_Drawing_BrushSetColor(brush, 0xffff0000); 302// Set the color matrix. 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// Create a filter color. 311OH_Drawing_ColorFilter* colorFilter = OH_Drawing_ColorFilterCreateMatrix(matrix); 312Creates an **OH_Drawing_Filter** object. 313OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); 314// Set the color filter for the filter object. 315OH_Drawing_FilterSetColorFilter(filter, colorFilter); 316// Set the filter effect of the brush. 317OH_Drawing_BrushSetFilter(brush, filter); 318// Set the brush on the canvas. Ensure that the canvas object has been obtained. 319OH_Drawing_CanvasAttachBrush(canvas, brush); 320// Create a rectangle. 321OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900); 322// Draw a rectangle. 323OH_Drawing_CanvasDrawRect(canvas, rect); 324// Remove the brush from the canvas. 325OH_Drawing_CanvasDetachBrush(canvas); 326// Destroy various objects. 327OH_Drawing_BrushDestroy(brush); 328OH_Drawing_ColorFilterDestroy(colorFilter); 329OH_Drawing_RectDestroy(rect); 330OH_Drawing_FilterDestroy(filter); 331``` 332 333| Effect when the color filter is not set| Setting the color filter effect of the 5x4 color matrix| 334| -------- | -------- | 335|  |  | 336 337 338### Image Filter Effects 339 340The image filter can be implemented based on the pen or pen. For details about the image filter APIs and parameters, see [drawing_image_filter.h](../reference/apis-arkgraphics2d/drawing__image__filter_8h.md). 341 342Currently, only two types of image filters are supported: 343 344- Image filter based on the color filter. 345 This function can be implemented by calling OH_Drawing_ImageFilterCreateFromColorFilter(). The interface accepts two parameters: colorFilter and input. That is, the effect of the color filter is superimposed on the input of the image filter. The input can be null, if input is empty, only the color filter effect is added. 346 347- Creates an image filter with a given blur effect. 348 This function can be implemented by calling OH_Drawing_ImageFilterCreateBlur(). The interface accepts four parameters: blur standard deviation on the X axis, blur standard deviation on the Y axis, tile mode, and image filter (input). 349 350 The final effect is to perform blurring processing based on the input image filter (input). That is, the filter effect can be superimposed. The input can be empty. If the input is empty, only the blur effect is added. 351 352The following uses drawing a rectangle and using a pen to add the blur effect to the image filter as an example. The following figure shows the key example and effect. 353 354```c++ 355// Create a pen. 356OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); 357// Set the pen anti-aliasing. 358OH_Drawing_PenSetAntiAlias(pen, true); 359// Set the stroke color. 360OH_Drawing_PenSetColor(pen, 0xffff0000); 361// Set the line width of the pen. 362OH_Drawing_PenSetWidth(pen, 20); 363// Create an image filter to implement the blur effect. 364OH_Drawing_ImageFilter *imageFilter = 365 OH_Drawing_ImageFilterCreateBlur(20.0f, 20.0f, OH_Drawing_TileMode::CLAMP, nullptr); 366Creates an **OH_Drawing_Filter** object. 367OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); 368// Set the image filter for the filter object. 369OH_Drawing_FilterSetImageFilter(filter, imageFilter); 370// Set the filter effect of the pen. 371OH_Drawing_PenSetFilter(pen, filter); 372// Set the pen on the canvas. Ensure that the canvas object has been obtained. 373OH_Drawing_CanvasAttachPen(canvas, pen); 374// Create a rectangle. 375OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900); 376// Draw a rectangle. 377OH_Drawing_CanvasDrawRect(canvas, rect); 378// Remove the pen from the canvas. 379OH_Drawing_CanvasDetachPen(canvas); 380// Destroy various objects. 381OH_Drawing_PenDestroy(pen); 382OH_Drawing_ImageFilterDestroy(imageFilter); 383OH_Drawing_RectDestroy(rect); 384OH_Drawing_FilterDestroy(filter); 385``` 386 387| Effect when no image filter is set| Setting the image filter effect| 388| -------- | -------- | 389|  |  | 390 391 392### Mask Filter Effects 393 394The blur effect of the mask filter blurs only the transparency and shape edges. Compared with the blur effect of the image filter, the calculation cost of the mask filter is lower. 395 396The mask filter can be implemented based on the pen or pen. For details about the mask filter APIs and parameters, see [drawing_mask_filter.h](../reference/apis-arkgraphics2d/drawing__mask__filter_8h.md). 397 398You can call H_Drawing_MaskFilterCreateBlur() to create a mask filter with the blur effect. The interface accepts the following parameters: 399 400- blurType: fuzzy type to be applied. For details, see [BlurType](../reference/apis-arkgraphics2d/js-apis-graphics-drawing.md#blurtype12). 401 402- sigma: specifies the standard deviation of the Gaussian blur to be applied. The standard deviation must be greater than 0. 403 404- respectCTM: whether the standard deviation of the blur is modified by the coordinate transformation matrix (CTM). The default value is true, indicating that the standard deviation is modified accordingly. 405 406The following describes how to draw a rectangle and use a pen to set the mask filter effect. The following figure shows the key example and effect. 407 408```c++ 409// Create a pen. 410OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); 411// Set the pen anti-aliasing. 412OH_Drawing_PenSetAntiAlias(pen, true); 413// Set the stroke color. 414OH_Drawing_PenSetColor(pen, 0xffff0000); 415// Set the line width of the pen. 416OH_Drawing_PenSetWidth(pen, 20); 417// Create a mask filter. 418OH_Drawing_MaskFilter *maskFilter = OH_Drawing_MaskFilterCreateBlur(OH_Drawing_BlurType::NORMAL, 20, true); 419Creates an **OH_Drawing_Filter** object. 420OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); 421// Set a mask filter for the filter object. 422OH_Drawing_FilterSetMaskFilter(filter, maskFilter); 423// Set the filter effect of the pen. 424OH_Drawing_PenSetFilter(pen, filter); 425// Set the pen on the canvas. Ensure that the canvas object has been obtained. 426OH_Drawing_CanvasAttachPen(canvas, pen); 427// Create a rectangle. 428OH_Drawing_Rect *rect = OH_Drawing_RectCreate(300, 300, 900, 900); 429// Draw a rectangle. 430OH_Drawing_CanvasDrawRect(canvas, rect); 431// Remove the pen from the canvas. 432OH_Drawing_CanvasDetachPen(canvas); 433// Destroy various objects. 434OH_Drawing_PenDestroy(pen); 435OH_Drawing_MaskFilterDestroy(maskFilter); 436OH_Drawing_RectDestroy(rect); 437OH_Drawing_FilterDestroy(filter); 438``` 439 440| Effect when no mask filter is set| Setting the mask filter effect| 441| -------- | -------- | 442|  |  | 443