1# 使用PixelMap完成位图操作
2
3当需要对目标图片中的部分区域进行处理时,可以使用位图操作功能。此功能常用于图片美化等操作。
4
5如下图所示,一张图片中,将指定的矩形区域像素数据读取出来,进行修改后,再写回原图片对应区域。
6
7**图1** 位图操作示意图
8
9![Bitmap operation](figures/bitmap-operation.png)
10
11## 开发步骤
12
13位图操作相关API的详细介绍请参见[API参考](../../reference/apis-image-kit/js-apis-image.md#pixelmap7)。
14
151. 完成[图片解码](image-decoding.md),获取PixelMap位图对象。
16
172. 从PixelMap位图对象中获取信息。
18
19   ```ts
20   import { image } from '@kit.ImageKit';
21   // 获取图像像素的总字节数
22   let pixelBytesNumber : number = pixelMap.getPixelBytesNumber();
23   // 获取图像像素每行字节数
24   let rowBytes : number = pixelMap.getBytesNumberPerRow();
25   // 获取当前图像像素密度。像素密度是指每英寸图片所拥有的像素数量。像素密度越大,图片越精细。
26   let density : number = pixelMap.getDensity();
27   ```
28
293. 读取并修改目标区域像素数据,写回原图。
30   > **说明:**
31   > 建议readPixelsToBuffer和writeBufferToPixels成对使用,readPixels和writePixels成对使用,避免因图像像素格式不一致,造成PixelMap图像出现异常。
32
33   ```ts
34   import { BusinessError } from '@kit.BasicServicesKit';
35   // 场景一:读取并修改整张图片数据
36   // 按照PixelMap的像素格式,读取PixelMap的图像像素数据,并写入缓冲区中。
37   const buffer = new ArrayBuffer(pixelBytesNumber);
38   pixelMap.readPixelsToBuffer(buffer).then(() => {
39     console.info('Succeeded in reading image pixel data.');
40   }).catch((error : BusinessError) => {
41     console.error('Failed to read image pixel data. The error is: ' + error);
42   })
43   // 按照PixelMap的像素格式,读取缓冲区中的图像像素数据,并写入PixelMap。
44   pixelMap.writeBufferToPixels(buffer).then(() => {
45     console.info('Succeeded in writing image pixel data.');
46   }).catch((error : BusinessError) => {
47     console.error('Failed to write image pixel data. The error is: ' + error);
48   })
49
50   // 场景二:读取并修改指定区域内的图片数据
51   // 固定按照BGRA_8888格式,读取PixelMap指定区域内的图像像素数据,并写入PositionArea.pixels缓冲区中,该区域由PositionArea.region指定。
52   const area : image.PositionArea = {
53     pixels: new ArrayBuffer(8),
54     offset: 0,
55     stride: 8,
56     region: { size: { height: 1, width: 2 }, x: 0, y: 0 }
57   }
58   pixelMap.readPixels(area).then(() => {
59     console.info('Succeeded in reading the image data in the area.');
60   }).catch((error : BusinessError) => {
61     console.error('Failed to read the image data in the area. The error is: ' + error);
62   })
63   // 固定按照BGRA_8888格式,读取PositionArea.pixels缓冲区中的图像像素数据,并写入PixelMap指定区域内,该区域由PositionArea.region指定。
64   pixelMap.writePixels(area).then(() => {
65     console.info('Succeeded in writing the image data in the area.');
66   }).catch((error : BusinessError) => {
67     console.error('Failed to write the image data in the area. The error is: ' + error);
68   })
69   ```
70
71## 开发示例-复制(深拷贝)新的PixelMap
72
731. 完成[图片解码](image-decoding.md),获取PixelMap位图对象。
74
752. 复制(深拷贝)一个新的PixelMap。
76   > **说明:**
77   > 创建新PixelMap时,必须将`srcPixelFormat`指定为原PixelMap的像素格式,否则新PixelMap的图像会出现异常。
78
79     ```ts
80      /**
81       *  复制(深拷贝)一个新的PixelMap
82       *
83       * @param pixelMap - 被复制的PixelMap。
84       * @param desiredPixelFormat - 新PixelMap的像素格式。如果不指定,则仍使用原PixelMap的像素格式。
85       * @returns 新PixelMap。
86       **/
87      clonePixelMap(pixelMap: PixelMap, desiredPixelFormat?: image.PixelMapFormat): PixelMap {
88        // 获取当前PixelMap的图片信息。
89        const imageInfo = pixelMap.getImageInfoSync();
90        // 读取当前PixelMap的图像像素数据,并按照当前PixelMap的像素格式写入缓冲区数组。
91        const buffer = new ArrayBuffer(pixelMap.getPixelBytesNumber());
92        pixelMap.readPixelsToBufferSync(buffer);
93        // 根据当前PixelMap的图片信息,生成初始化选项。
94        const options: image.InitializationOptions = {
95          // 当前PixelMap的像素格式。
96          srcPixelFormat: imageInfo.pixelFormat,
97          // 新PixelMap的像素格式。
98          pixelFormat: desiredPixelFormat ?? imageInfo.pixelFormat,
99          // 当前PixelMap的尺寸大小。
100          size: imageInfo.size
101        };
102        // 根据初始化选项和缓冲区数组,生成新PixelMap。
103        return image.createPixelMapSync(buffer, options);
104      }
105     ```
106
107<!--RP1-->
108<!--RP1End-->