• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 图片开发指导
2
3## 场景介绍
4
5图片开发的主要工作是将获取到的图片进行解码,将解码后的pixelmap编码成支持的格式,本文将对图片的解码、编码等场景开发进行介绍说明。
6
7## 接口说明
8
9详细API含义请参考:[图片处理API文档](../reference/apis/js-apis-image.md)
10
11## 开发步骤
12
13### 全流程场景
14
15包含流程:创建实例、读取图片信息、读写pixelmap、更新数据、打包像素、释放资源等流程。
16
17```js
18const color = new ArrayBuffer(96); // 用于存放图像像素数据
19let opts = { alphaType: 0, editable: true, pixelFormat: 4, scaleMode: 1, size: { height: 2, width: 3 } } // 图像像素数据
20
21// 创建pixelmap对象
22image.createPixelMap(color, opts, (err, pixelmap) => {
23    console.log('Succeeded in creating pixelmap.');
24    // 创建pixelmap对象失败
25    if (err) {
26        console.info('create pixelmap failed, err' + err);
27        return
28    }
29
30    // 用于读像素
31    const area = {
32        pixels: new ArrayBuffer(8),
33        offset: 0,
34        stride: 8,
35        region: { size: { height: 1, width: 2 }, x: 0, y: 0 }
36    }
37    pixelmap.readPixels(area,() => {
38        let bufferArr = new Uint8Array(area.pixels);
39        let res = true;
40        for (let i = 0; i < bufferArr.length; i++) {
41            console.info(' buffer ' + bufferArr[i]);
42            if(res) {
43                if(bufferArr[i] == 0) {
44                    res = false;
45                    console.log('readPixels end.');
46                    break;
47                }
48            }
49        }
50    })
51
52    // 用于存像素
53    const readBuffer = new ArrayBuffer(96);
54    pixelmap.readPixelsToBuffer(readBuffer,() => {
55        let bufferArr = new Uint8Array(readBuffer);
56        let res = true;
57        for (let i = 0; i < bufferArr.length; i++) {
58            if(res) {
59                if (bufferArr[i] !== 0) {
60                    res = false;
61                    console.log('readPixelsToBuffer end.');
62                    break;
63                }
64            }
65        }
66    })
67
68    // 用于写像素
69    pixelmap.writePixels(area,() => {
70        const readArea = { pixels: new ArrayBuffer(20), offset: 0, stride: 8, region: { size: { height: 1, width: 2 }, x: 0, y: 0 }}
71        pixelmap.readPixels(readArea,() => {
72            let readArr = new Uint8Array(readArea.pixels);
73            let res = true;
74            for (let i = 0; i < readArr.length; i++) {
75                if(res) {
76                    if (readArr[i] !== 0) {
77                        res = false;
78                        console.log('readPixels end.please check buffer');
79                        break;
80                    }
81                }
82            }
83        })
84    })
85
86    const writeColor = new ArrayBuffer(96); //图像像素数据
87    // 用于写像素到缓冲区
88    pixelmap.writeBufferToPixels(writeColor).then(() => {
89        const readBuffer = new ArrayBuffer(96);
90        pixelmap.readPixelsToBuffer(readBuffer).then (() => {
91            let bufferArr = new Uint8Array(readBuffer);
92            let res = true;
93            for (let i = 0; i < bufferArr.length; i++) {
94                if(res) {
95                    if (bufferArr[i] !== i) {
96                        res = false;
97                        console.log('readPixels end.please check buffer');
98                        break;
99                    }
100                }
101            }
102        })
103    })
104
105    // 用于获取图片信息
106    pixelmap.getImageInfo((err, imageInfo) => {
107        // 获取图片信息失败
108        if (err || imageInfo == null) {
109            console.info('getImageInfo failed, err' + err);
110            return
111        }
112        if (imageInfo !== null) {
113            console.log('Succeeded in getting imageInfo');
114        }
115    })
116
117    // 用于释放pixelmap
118    pixelmap.release(()=>{
119        console.log('Succeeded in releasing pixelmap');
120    })
121})
122
123// 用于创建imagesource(uri)
124let path = '/data/local/tmp/test.jpg';
125const imageSourceApi1 = image.createImageSource(path);
126
127// 用于创建imagesource(fd)
128let fd = 29;
129const imageSourceApi2 = image.createImageSource(fd);
130
131// 用于创建imagesource(data)
132const data = new ArrayBuffer(96);
133const imageSourceApi3 = image.createImageSource(data);
134
135// 用于释放imagesource
136imageSourceApi3.release(() => {
137    console.log('Succeeded in releasing imagesource');
138})
139
140// 用于编码
141const imagePackerApi = image.createImagePacker();
142const imageSourceApi = image.createImageSource(0);
143let packOpts = { format:"image/jpeg", quality:98 };
144imagePackerApi.packing(imageSourceApi, packOpts, (err, data) => {
145    if (err) {
146        console.info('packing from imagePackerApi failed, err' + err);
147        return
148    }
149    console.log('Succeeded in packing');
150})
151
152// 用于释放imagepacker
153imagePackerApi.release();
154```
155
156### 解码场景
157
158```js
159let path = '/data/local/tmp/test.jpg'; // 设置创建imagesource的路径
160
161// 用路径创建imagesource
162const imageSourceApi = image.createImageSource(path); // '/data/local/tmp/test.jpg'
163
164// 设置参数
165let decodingOptions = {
166    sampleSize:1, // 缩略图采样大小
167    editable: true, // 是否可编辑
168    desiredSize:{ width:1, height:2}, // 期望输出大小
169    rotateDegrees:10, // 旋转角度
170    desiredPixelFormat:2, // 解码的像素格式
171    desiredRegion: { size: { height: 1, width: 2 }, x: 0, y: 0 }, // 解码的区域
172    index:0 // 图片序号
173    };
174
175// 用于回调方式创建pixelmap
176imageSourceApi.createPixelMap(decodingOptions, (err, pixelmap) => {
177    // 创建pixelmap对象失败
178    if (err) {
179        console.info('create pixelmap failed, err' + err);
180        return
181    }
182    console.log('Succeeded in creating pixelmap.');
183})
184
185// 用于promise创建pixelmap
186imageSourceApi.createPixelMap().then(pixelmap => {
187    console.log('Succeeded in creating pixelmap.');
188
189    // 用于获取像素每行字节数
190    let num = pixelmap.getBytesNumberPerRow();
191
192    // 用于获取像素总字节数
193    let pixelSize = pixelmap.getPixelBytesNumber();
194
195    // 用于获取pixelmap信息
196    pixelmap.getImageInfo().then( imageInfo => {});
197
198    // 用于释放pixelmap
199    pixelmap.release(()=>{
200        console.log('Succeeded in releasing pixelmap');
201    })
202}).catch(error => {
203    console.log('Failed in creating pixelmap.' + error);
204})
205```
206
207### 编码场景
208
209```js
210let path = '/data/local/tmp/test.png'; // 设置创建imagesource的路径
211
212// 用于设置imagesource
213const imageSourceApi = image.createImageSource(path); // '/data/local/tmp/test.png'
214
215// 如果创建imagesource失败,打印错误信息
216if (imageSourceApi == null) {
217    console.log('Failed in creating imageSource.');
218}
219
220// 如果创建imagesource成功,则创建imagepacker
221const imagePackerApi = image.createImagePacker();
222
223// 如果创建失败,打印错误信息
224if (imagePackerApi == null) {
225    console.log('Failed in creating imagePacker.');
226}
227
228// 如果创建imagepacker成功,则设置编码参数
229let packOpts = { format:"image/jpeg", // 支持编码的格式为jpg
230                 quality:98 } // 图片质量0-100
231
232// 用于编码
233imagePackerApi.packing(imageSourceApi, packOpts)
234.then( data => {
235    console.log('Succeeded in packing');
236})
237
238// 编码完成,释放imagepacker
239imagePackerApi.release();
240
241// 用于获取imagesource信息
242imageSourceApi.getImageInfo((err, imageInfo) => {
243    console.log('Succeeded in getting imageInfo');
244})
245
246const array = new ArrayBuffer(100); //增量数据
247// 用于更新增量数据
248imageSourceApi.updateData(array, false, 0, 10,(error, data)=> {})
249
250```
251
252### ImageReceiver的使用
253
254示例场景:camera作为客户端将拍照数据传给服务端
255
256```js
257public async init(surfaceId: any) {
258
259    // 服务端代码,创建ImageReceiver
260    let receiver = image.createImageReceiver(8 * 1024, 8, image.ImageFormat.JPEG, 1);
261
262    // 获取Surface ID
263    receiver.getReceivingSurfaceId((err, surfaceId) => {
264    // 获取Surface ID失败
265        if (err) {
266            console.info('getReceivingSurfaceId failed, err' + err);
267            return
268        }
269        console.info("receiver getReceivingSurfaceId success");
270    });
271    // 注册Surface的监听,在surface的buffer准备好后触发
272    receiver.on('imageArrival', () => {
273        // 去获取Surface中最新的buffer
274        receiver.readNextImage((err, img) => {
275            img.getComponent(4, (err, component) => {
276                // 消费component.byteBuffer,例如:将buffer内容保存成图片。
277		    })
278	    })
279    })
280
281    // 调用Camera方法将surfaceId传递给Camera。camera会通过surfaceId获取surface,并生产出surface buffer。
282}
283```
284
285## 相关实例
286
287针对图片开发,有以下相关实例可供参考:
288
289- [`Image`:图片处理(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/media/Image)
290- [`GamePuzzle`:拼图(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/media/GamePuzzle)