画布操作及状态处理（C/C++）
================

#### 场景介绍

创建或获取Canvas画布之后，可以基于画布进一步地进行图形操作和状态处理。画布操作属于可选操作，开发者可以根据场景需要进行。需要先进行画布操作，再进行后续绘制，只有这样画布操作才有效果。

常见的画布操作如下：

*   裁剪。
    
*   矩阵变换，如平移、缩放、旋转等。
    
*   状态保存与恢复。
    

#### 裁剪操作

裁剪是图形处理中的常见操作，裁剪针对的是画布本身，可以用于限制绘图区域，只在指定的区域内进行绘制。需要先进行裁剪操作，再进行绘制，才会有对应效果。

当前支持的裁剪操作主要如下：

*   裁剪矩形。
    
*   裁剪圆角矩形。
    
*   裁剪自定义路径。
    
*   裁剪一个区域。
    

#### \[h2\]接口说明

裁剪操作常用接口如下表所示，详细的使用和参数说明请见[drawing\_canvas.h](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-canvas-h)。

| 接口 | 描述 |
| :-- | :-- |
| void OH\_Drawing\_CanvasClipRect (OH\_Drawing\_Canvas \*, const OH\_Drawing\_Rect \*, OH\_Drawing\_CanvasClipOp clipOp, bool doAntiAlias) | 用于裁剪一个矩形。 |
| void OH\_Drawing\_CanvasClipRoundRect (OH\_Drawing\_Canvas \*, const OH\_Drawing\_RoundRect \*, OH\_Drawing\_CanvasClipOp clipOp, bool doAntiAlias) | 用于裁剪一个圆角矩形。 |
| void OH\_Drawing\_CanvasClipPath (OH\_Drawing\_Canvas \*, const OH\_Drawing\_Path \*, OH\_Drawing\_CanvasClipOp clipOp, bool doAntiAlias) | 用于裁剪一个自定义路径。 |
| OH\_Drawing\_ErrorCode OH\_Drawing\_CanvasClipRegion (OH\_Drawing\_Canvas \*canvas, const OH\_Drawing\_Region \*region, OH\_Drawing\_CanvasClipOp clipOp) | 用于裁剪一个区域。 |

#### \[h2\]开发示例

此处以在画布上裁剪矩形为例给出示例和效果图，其他裁剪操作的逻辑基本相同，注意调用对应的接口并确保要裁剪的数据类型对应准确即可，此处不再一一展开。详细的使用和参数说明请见[drawing\_canvas.h](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-canvas-h)。

使用OH\_Drawing\_CanvasClipRect接口裁剪矩形。有以下四个入参：

*   第一个参数是画布Canvas，裁剪操作将在这个画布上进行。请确保已创建或获取得到画布Canvas，具体可见[画布的获取与绘制结果的显示（C/C++）](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/canvas-get-result-draw-c)。
    
*   第二个参数是要裁剪的矩形区域。
    
*   第三个参数是裁剪的操作类型，包括交集（INTERSECT）和差集（DIFFERENCE）。
    
*   第四个参数表示是否需要进行抗锯齿处理。
    

// 创建画刷对象
OH\_Drawing\_Brush \*brush = OH\_Drawing\_BrushCreate();
// 设置画刷填充颜色为蓝色
OH\_Drawing\_BrushSetColor(brush, 0xff0000ff);
// 在画布中设置画刷
OH\_Drawing\_CanvasAttachBrush(canvas, brush);
OH\_Drawing\_Rect \*rect = OH\_Drawing\_RectCreate(value400\_, value400\_, value1200\_, value1200\_);
// 裁剪矩形区域
OH\_Drawing\_CanvasClipRect(canvas, rect, OH\_Drawing\_CanvasClipOp::INTERSECT, true);
OH\_Drawing\_Point \*point = OH\_Drawing\_PointCreate(value600\_, value600\_);
// 绘制圆形
OH\_Drawing\_CanvasDrawCircle(canvas, point, value600\_);
// 去除画布中的画刷
OH\_Drawing\_CanvasDetachBrush(canvas);
// 销毁画刷对象并收回其占的内存
OH\_Drawing\_BrushDestroy(brush);

| 原始图 | 裁剪后的图 |
| :-- | :-- |
| ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d8/v3/XKF73WRWRZykePX0knf1Ww/zh-cn_image_0000002664328569.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=3244A2B7B2032B2DA5CC6845F9B9BC9BB7A2E28FB336AA7DFE6145F152693A78) | ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/cd/v3/w74uhgFWReWJNZSSKeXhWw/zh-cn_image_0000002633849458.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=3AFA1959C6859BB4222DDD314F7C367DCFBDDE4AE99817D440E0A66129187D0F) |

#### 矩阵变换操作

矩阵变换也是常见的画布操作，是一种坐标系的转换，用于进行图形的变化。

当前支持的矩阵变换主要如下：

*   平移
    
*   缩放
    
*   旋转
    

#### \[h2\]接口说明

矩阵变换操作常用接口如下表所示，详细的使用和参数说明请见[drawing\_canvas.h](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-canvas-h)。

| 接口 | 描述 |
| :-- | :-- |
| void OH\_Drawing\_CanvasTranslate (OH\_Drawing\_Canvas \*, float dx, float dy) | 用于平移画布一段距离。 |
| void OH\_Drawing\_CanvasScale (OH\_Drawing\_Canvas \*, float sx, float sy) | 用于画布缩放。 |
| void OH\_Drawing\_CanvasRotate (OH\_Drawing\_Canvas \*, float degrees, float px, float py) | 用于画布旋转一定的角度，正数表示顺时针旋转，负数反之。 |
| void OH\_Drawing\_CanvasSkew (OH\_Drawing\_Canvas \*, float sx, float sy) | 用于画布倾斜变换。等同于将当前画布矩阵左乘（premultiply）倾斜变换矩阵，并应用到画布上。其中倾斜变换矩阵为：|1 sx 0| |sy 1 0| |0 0 1|。 |

#### \[h2\]平移

使用OH\_Drawing\_MatrixCreateTranslation()接口实现画布平移。接口接受2个参数，分别为水平方向和垂直方向的平移量，单位为px。

简单示例和示意图如下所示：

// 创建画刷对象
OH\_Drawing\_Brush\* brush = OH\_Drawing\_BrushCreate();
// 设置填充颜色
OH\_Drawing\_BrushSetColor(brush, OH\_Drawing\_ColorSetArgb(RGBA\_MAX, RGBA\_MAX, RGBA\_MIN, RGBA\_MIN));
// 设置画布中的画刷
OH\_Drawing\_CanvasAttachBrush(canvas, brush);
// 创建在水平和垂直方向分别平移300px的矩阵对象
OH\_Drawing\_Matrix \*matrix = OH\_Drawing\_MatrixCreateTranslation(value300\_, value300\_);
// 对Canvas进行矩阵变换
OH\_Drawing\_CanvasConcatMatrix(canvas, matrix);
// 绘制矩形
OH\_Drawing\_Rect \*rect = OH\_Drawing\_RectCreate(value200\_, value300\_, value700\_, value600\_);
OH\_Drawing\_CanvasDrawRect(canvas, rect);
// 去除画布中的画刷
OH\_Drawing\_CanvasDetachBrush(canvas);
OH\_Drawing\_RectDestroy(rect);
OH\_Drawing\_MatrixDestroy(matrix);

| 原始图 | 平移后的效果图 |
| :-- | :-- |
| ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/02/v3/DnbpWsEORACRoY1LPESU-w/zh-cn_image_0000002664208513.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=47202AEC75B4E0FD6E0691441F44488DD9D0FBD9FBDF7415930C6106F1B6B49E) | ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/3e/v3/hS1oQvusSjyzaJ1EdpizqQ/zh-cn_image_0000002664328573.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=8E391F92416E57DC0BC2706DAD5CBE3906D03AB0E563C396D586012F81623953) |

#### \[h2\]旋转

使用OH\_Drawing\_MatrixCreateRotation()接口实现画布旋转，接口接受3个参数，分别为：旋转角度、旋转中心的x坐标和y坐标。

简单示例和示意图如下所示：

// 创建画刷对象
OH\_Drawing\_Brush\* brush = OH\_Drawing\_BrushCreate();
// 设置填充颜色
OH\_Drawing\_BrushSetColor(brush, OH\_Drawing\_ColorSetArgb(RGBA\_MAX, RGBA\_MAX, RGBA\_MIN, RGBA\_MIN));
// 设置画布中的画刷
OH\_Drawing\_CanvasAttachBrush(canvas, brush);
// 创建旋转的矩阵对象，三个参数分别是旋转角度和旋转中心坐标
OH\_Drawing\_Matrix\* matrix = OH\_Drawing\_MatrixCreateRotation(45, value200\_, value300\_);
// 对Canvas进行矩阵变换
OH\_Drawing\_CanvasConcatMatrix(canvas, matrix);
// 绘制矩形
OH\_Drawing\_Rect \*rect = OH\_Drawing\_RectCreate(value200\_, value300\_, value700\_, value600\_);
OH\_Drawing\_CanvasDrawRect(canvas, rect);
// 去除画布中的画刷
OH\_Drawing\_CanvasDetachBrush(canvas);
OH\_Drawing\_RectDestroy(rect);
OH\_Drawing\_MatrixDestroy(matrix);

| 原始图 | 旋转后的效果图 |
| :-- | :-- |
| ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/24/v3/EMJ0HyxlTwaEh5yr6VOhFQ/zh-cn_image_0000002633849462.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=988C9AA2EC42BD29262BD4132C8B0A71655FEC828DD1E2C64493C97E2DEFF080) | ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/19/v3/8aVT_D5hTI-Q7AgZ7FaZkg/zh-cn_image_0000002634009366.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=EAA9B6F8E3B5A07768D0A41B9FBCF8E0D0EBC3F09E3E88A8FCB50908F2DFA977) |

#### \[h2\]缩放

使用OH\_Drawing\_MatrixCreateScale()接口进行画布缩放，接口接受4个参数，分别为沿x轴和y轴的缩放因子、旋转中心的x轴和y轴坐标。

简单示例和示意图如下所示：

// 创建画刷对象
OH\_Drawing\_Brush\* brush = OH\_Drawing\_BrushCreate();
// 设置填充颜色
OH\_Drawing\_BrushSetColor(brush, OH\_Drawing\_ColorSetArgb(RGBA\_MAX, RGBA\_MAX, RGBA\_MIN, RGBA\_MIN));
// 设置画布中的画刷
OH\_Drawing\_CanvasAttachBrush(canvas, brush);
// 创建缩放的矩阵对象，4个参数分别是旋转中心坐标和水平垂直方向的缩放因子
OH\_Drawing\_Matrix\* matrix = OH\_Drawing\_MatrixCreateScale(2, 2, value200\_, value300\_);
// 对Canvas进行矩阵变换
OH\_Drawing\_CanvasConcatMatrix(canvas, matrix);
// 绘制矩形
OH\_Drawing\_Rect \*rect = OH\_Drawing\_RectCreate(value200\_, value300\_, value700\_, value600\_);
OH\_Drawing\_CanvasDrawRect(canvas, rect);
// 去除画布中的画刷
OH\_Drawing\_CanvasDetachBrush(canvas);
OH\_Drawing\_RectDestroy(rect);

| 原始图 | 放大后的效果图 |
| :-- | :-- |
| ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/23/v3/vUCk7ahvRcyPAImw3OOWqw/zh-cn_image_0000002664208515.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=0378E433279F01722094675B9EFD0DE6DC3A45812FE6A691ED6D871ED090CFCD) | ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/5c/v3/1qISE-IXROaizGOaS5dQiQ/zh-cn_image_0000002664328575.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=4865B9D781FD193C453F6909623EDF42A96C56B40042DF5F513880543D692561) |

#### 画布状态保存与恢复

保存操作用于保存当前画布的状态到一个栈顶，恢复操作用于恢复保存在栈顶的画布状态，恢复操作一旦执行，保存和恢复操作中间一系列平移、缩放、裁剪等操作都会被清除。

#### \[h2\]接口说明

画布状态保存与恢复使用的接口如下表所示，详细的使用和参数说明请见[drawing\_canvas.h](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing-canvas-h)。

| 接口 | 描述 |
| :-- | :-- |
| void OH\_Drawing\_CanvasSave (OH\_Drawing\_Canvas \*) | 用于保存当前画布的状态（画布矩阵）到一个栈顶。 |
| void OH\_Drawing\_CanvasRestore (OH\_Drawing\_Canvas \*) | 用于恢复保存在栈顶的画布状态（画布矩阵）。 |
| void OH\_Drawing\_CanvasRestoreToCount (OH\_Drawing\_Canvas \*, uint32\_t saveCount) | 用于恢复到指定数量的画布状态（画布矩阵）。 |

#### \[h2\]开发示例

// 创建画笔对象
OH\_Drawing\_Pen\* pen = OH\_Drawing\_PenCreate();
// 设置画笔描边颜色
OH\_Drawing\_PenSetColor(pen, OH\_Drawing\_ColorSetArgb(RGBA\_MAX, RGBA\_MAX, RGBA\_MIN, RGBA\_MIN));
// 设置画笔线宽为20
OH\_Drawing\_PenSetWidth(pen, 20);
// 在画布中设置画笔
OH\_Drawing\_CanvasAttachPen(canvas, pen);
// 保存当前画布状态，当前是不存在放大等操作的，这个原始状态会被保存下来
OH\_Drawing\_CanvasSave(canvas);
OH\_Drawing\_Matrix \*matrix = OH\_Drawing\_MatrixCreateScale(2, 2, 2, 2);
// 放大画布
OH\_Drawing\_CanvasConcatMatrix(canvas, matrix);
OH\_Drawing\_Point\* point = OH\_Drawing\_PointCreate(value300\_, value300\_);
// 绘制圆形，因为执行过放大操作，所以此时绘制的是大圆
OH\_Drawing\_CanvasDrawCircle(canvas, point, value200\_);
// 恢复操作，将恢复到没有放大的原始状态
OH\_Drawing\_CanvasRestore(canvas);
// 绘制圆形，因为已经恢复没有放大的原始状态，所以此时绘制的小圆
OH\_Drawing\_CanvasDrawCircle(canvas, point, value200\_);
// 去除画布中的画笔
OH\_Drawing\_CanvasDetachPen(canvas);
// 销毁画笔对象并收回其占的内存
OH\_Drawing\_PenDestroy(pen);
OH\_Drawing\_PointDestroy(point);
OH\_Drawing\_MatrixDestroy(matrix);

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6e/v3/Lx_L3bzIQ16lak5BsGFLwg/zh-cn_image_0000002633849464.png?HW-CC-KV=V1&HW-CC-Date=20260709T132544Z&HW-CC-Expire=86400&HW-CC-Sign=926B5728A517BF3A611782D0D41A780194CFECD7C30AA9342ED3E7B7735B8B1C)

#### 示例代码

*   [图形绘制（C/C++）](https://gitcode.com/HarmonyOS_Samples/guide-snippets/tree/master/ArkGraphics2D/Drawing/NDKGraphicsDraw)