1# 画布操作及状态处理(C/C++) 2 3 4## 场景介绍 5 6创建或获取得到Canvas画布之后,可以基于画布进一步地进行图形操作和状态处理。画布操作属于可选操作,开发者可以根据场景需要进行。需要先进行画布操作,再进行后续绘制,只有这样画布操作才有效果。 7 8常见的画布操作如下: 9 10- 裁剪。 11 12- 矩阵变换,如平移、缩放、旋转等。 13 14- 状态保存与恢复。 15 16 17## 裁剪操作 18 19裁剪是图形处理中的常见操作,裁剪针对的是画布本身,可以用于限制绘图区域,只在指定的区域内容进行绘制。需要先进行裁剪操作,再进行绘制,才会有对应效果。 20 21当前支持的裁剪操作主要如下: 22 23- 裁剪矩形。 24 25- 裁剪圆角矩形。 26 27- 裁剪自定义路径。 28 29- 裁剪一个区域。 30 31 32### 接口说明 33 34裁剪操作常用接口如下表所示,详细的使用和参数说明请见[drawing_canvas.h](../reference/apis-arkgraphics2d/drawing__canvas_8h.md)。 35 36| 接口 | 描述 | 37| -------- | -------- | 38| void OH_Drawing_CanvasClipRect (OH_Drawing_Canvas \*, const OH_Drawing_Rect \*, OH_Drawing_CanvasClipOp clipOp, bool doAntiAlias) | 用于裁剪一个矩形。 | 39| void OH_Drawing_CanvasClipRoundRect (OH_Drawing_Canvas \*, const OH_Drawing_RoundRect \*, OH_Drawing_CanvasClipOp clipOp, bool doAntiAlias) | 用于裁剪一个圆角矩形。 | 40| void OH_Drawing_CanvasClipPath (OH_Drawing_Canvas \*, const OH_Drawing_Path \*, OH_Drawing_CanvasClipOp clipOp, bool doAntiAlias) | 用于裁剪一个自定义路径。 | 41| OH_Drawing_ErrorCode OH_Drawing_CanvasClipRegion (OH_Drawing_Canvas \*canvas, const OH_Drawing_Region \*region, OH_Drawing_CanvasClipOp clipOp) | 用于裁剪一个区域。 | 42 43 44### 开发示例 45 46此处以在画布上裁剪矩形为例给出示例和效果图,其他裁剪操作的逻辑基本相同,注意调用对应的接口并确保要裁剪的数据类型对应准确即可,此处不再一一展开。具体详细的使用和参数说明请见[drawing_canvas.h](../reference/apis-arkgraphics2d/drawing__canvas_8h.md)。 47 48使用OH_Drawing_CanvasClipRect接口裁剪矩形。有以下四个入参: 49- 第一个参数是画布Canvas,裁剪操作将在这个画布上进行。请确保已创建或获取得到画布Canvas,具体可见[画布的获取与绘制结果的显示(C/C++)](canvas-get-result-draw-c.md)。 50 51- 第二个参数是要裁剪的矩形区域。 52 53- 第三个参数是裁剪的操作类型,包括交集(INTERSECT)和差集(DIFFERENCE)。 54 55- 第四个参数表示是否需要进行抗锯齿处理。 56 57```c++ 58// 创建画刷对象 59OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); 60// 设置画刷填充颜色为蓝色 61OH_Drawing_BrushSetColor(brush, 0xff0000ff); 62// 在画布中设置画刷 63OH_Drawing_CanvasAttachBrush(canvas, brush); 64OH_Drawing_Rect *rect = OH_Drawing_RectCreate(400, 400, 1200, 1200); 65// 裁剪矩形区域 66OH_Drawing_CanvasClipRect(canvas, rect, OH_Drawing_CanvasClipOp::INTERSECT, true); 67OH_Drawing_Point *point = OH_Drawing_PointCreate(600, 600); 68// 绘制圆形 69OH_Drawing_CanvasDrawCircle(canvas, point, 600); 70// 去除画布中的画刷 71OH_Drawing_CanvasDetachBrush(canvas); 72// 销毁画刷对象并收回其占的内存 73OH_Drawing_BrushDestroy(brush); 74``` 75 76| 原始图 | 裁剪后的图 | 77| -------- | -------- | 78|  |  | 79 80 81## 矩阵变化操作 82 83矩阵变换也是常见的画布操作,是一种坐标系的转换,用于进行图形的变化。 84 85当前支持的矩阵变换主要如下: 86 87- 平移 88 89- 缩放 90 91- 旋转 92 93 94### 接口说明 95 96矩阵变换操作常用接口如下表所示,详细的使用和参数说明请见[drawing_matrix.h](../reference/apis-arkgraphics2d/drawing__matrix_8h.md)。 97 98| 接口 | 描述 | 99| -------- | -------- | 100| void OH_Drawing_CanvasTranslate (OH_Drawing_Canvas \*, float dx, float dy) | 用于平移画布一段距离。 | 101| void OH_Drawing_CanvasScale (OH_Drawing_Canvas \*, float sx, float sy) | 用于画布缩放。 | 102| void OH_Drawing_CanvasRotate (OH_Drawing_Canvas \*, float degrees, float px, float py) | 用于画布旋转一定的角度,正数表示顺时针旋转,负数反之。 | 103| void OH_Drawing_CanvasSkew (OH_Drawing_Canvas \*, float sx, float sy) | 用于画布倾斜变换。等同于将当前画布矩阵左乘(premultiply)倾斜变换矩阵,并应用到画布上。其中倾斜变换矩阵为:\|1 sx 0\| \|sy 1 0\| \|0 0 1\|。 | 104 105 106### 平移 107 108使用OH_Drawing_MatrixCreateTranslation()接口实现画布平移。接口接受2个参数,分别为水平方向和垂直方向的平移量,单位为px。 109 110简单示例和示意图如下所示: 111 112```c++ 113// 创建画刷对象 114OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 115// 设置填充颜色 116OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); 117// 设置画布中的画刷 118OH_Drawing_CanvasAttachBrush(canvas, brush); 119// 创建在水平和垂直方向分别平移300px的矩阵对象 120OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreateTranslation(300, 300); 121// 对Canvas进行矩阵变换 122OH_Drawing_CanvasConcatMatrix(canvas, matrix); 123// 绘制矩形 124OH_Drawing_Rect *rect = OH_Drawing_RectCreate(200, 300, 700, 600); 125OH_Drawing_CanvasDrawRect(canvas, rect); 126// 去除画布中的画刷 127OH_Drawing_CanvasDetachBrush(canvas); 128OH_Drawing_RectDestroy(rect); 129OH_Drawing_MatrixDestroy(matrix); 130``` 131 132| 原始图 | 平移后的效果图 | 133| -------- | -------- | 134|  |  | 135 136 137### 旋转 138 139使用OH_Drawing_MatrixCreateRotation()接口实现画布旋转,接口接受3个参数,分别为:旋转角度、旋转中心的x坐标和y坐标。 140 141简单示例和示意图如下所示: 142 143```c++ 144// 创建画刷对象 145OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 146// 设置填充颜色 147OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); 148// 设置画布中的画刷 149OH_Drawing_CanvasAttachBrush(canvas, brush); 150// 创建旋转的矩阵对象,三个参数分别是旋转角度和旋转中心坐标 151OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateRotation(45, 200, 300); 152// 对Canvas进行矩阵变换 153OH_Drawing_CanvasConcatMatrix(canvas, matrix); 154// 绘制矩形 155OH_Drawing_Rect *rect = OH_Drawing_RectCreate(200, 300, 700, 600); 156OH_Drawing_CanvasDrawRect(canvas, rect); 157// 去除画布中的画刷 158OH_Drawing_CanvasDetachBrush(canvas); 159OH_Drawing_RectDestroy(rect); 160OH_Drawing_MatrixDestroy(matrix); 161``` 162 163| 原始图 | 旋转后的效果图 | 164| -------- | -------- | 165|  |  | 166 167 168### 缩放 169 170使用OH_Drawing_MatrixCreateScale()接口进行画布缩放,接口接受4个参数,分别为沿x轴和y轴的缩放因子、旋转中心的x轴和y轴坐标。 171 172简单示例和示意图如下所示: 173 174```c++ 175// 创建画刷对象 176OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); 177// 设置填充颜色 178OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); 179// 设置画布中的画刷 180OH_Drawing_CanvasAttachBrush(canvas, brush); 181// 创建缩放的矩阵对象,4个参数分别是旋转中心坐标和水平垂直方向的缩放因子 182OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateScale(2, 2, 200, 300); 183// 对Canvas进行矩阵变换 184OH_Drawing_CanvasConcatMatrix(canvas, matrix); 185// 绘制矩形 186OH_Drawing_Rect *rect = OH_Drawing_RectCreate(200, 300, 700, 600); 187OH_Drawing_CanvasDrawRect(canvas, rect); 188// 去除画布中的画刷 189OH_Drawing_CanvasDetachBrush(canvas); 190OH_Drawing_RectDestroy(rect); 191``` 192 193| 原始图 | 放大后的效果图 | 194| -------- | -------- | 195|  |  | 196 197 198## 画布状态保存与恢复 199 200保存操作用于保存当前画布的状态到一个栈顶,恢复操作用于恢复保存在栈顶的画布状态,恢复操作一旦执行,保存和恢复操作中间一系列平移、缩放、剪裁等操作都会被清除。 201 202 203### 接口说明 204 205画布状态保存与恢复使用的接口如下表所示,详细的使用和参数说明请见[drawing_canvas.h](../reference/apis-arkgraphics2d/drawing__canvas_8h.md)。 206 207| 接口 | 描述 | 208| -------- | -------- | 209| void OH_Drawing_CanvasSave (OH_Drawing_Canvas \*) | 用于保存当前画布的状态(画布矩阵)到一个栈顶。 | 210| void OH_Drawing_CanvasRestore (OH_Drawing_Canvas \*) | 用于恢复保存在栈顶的画布状态(画布矩阵)。 | 211| void OH_Drawing_CanvasRestoreToCount (OH_Drawing_Canvas \*, uint32_t saveCount) | 用于恢复到指定数量的画布状态(画布矩阵)。 | 212 213 214### 开发示例 215 216```c++ 217// 创建画笔对象 218OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); 219// 设置画笔描边颜色 220OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); 221// 设置画笔线宽 222OH_Drawing_PenSetWidth(pen, 20); 223// 在画布中设置画笔 224OH_Drawing_CanvasAttachPen(canvas, pen); 225// 保存当前画布状态,当前是不存在放大等操作的,这个原始状态会被保存下来 226OH_Drawing_CanvasSave(canvas); 227OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreateScale(2, 2, 2, 2); 228// 放大画布 229OH_Drawing_CanvasConcatMatrix(canvas, matrix); 230OH_Drawing_Point* point = OH_Drawing_PointCreate(300, 300); 231// 绘制圆形,因为执行过放大操作,所以此时绘制的是大圆 232OH_Drawing_CanvasDrawCircle(canvas, point, 200); 233// 恢复操作,将恢复到没有放大的原始状态 234OH_Drawing_CanvasRestore(canvas); 235// 绘制圆形,因为已经恢复没有放大的原始状态,所以此时绘制的小圆 236OH_Drawing_CanvasDrawCircle(canvas, point, 200); 237// 去除画布中的画笔 238OH_Drawing_CanvasDetachPen(canvas); 239// 销毁画笔对象并收回其占的内存 240OH_Drawing_PenDestroy(pen); 241OH_Drawing_PointDestroy(point); 242OH_Drawing_MatrixDestroy(matrix); 243``` 244 245 246 247<!--RP1--> 248## 相关实例 249 250针对Drawing(C/C++)的开发,有以下相关实例可供参考: 251 252- [NDKGraphicsDraw (API14)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Drawing/NDKGraphicsDraw) 253<!--RP1End-->