1# multimedia子系统变更说明
2
3## cl.multimedia.1 image.Component.rowStride接口返回值变更
4
5**访问级别**
6
7公开接口
8
9**变更原因**
10
11优化接口实现,当前返回值为图片的width,与接口定义不符,无法支撑开发者进行图片处理。
12
13**变更影响**
14
15该变更为兼容性变更。
16
17变更前:
18应用开发者根据预览流数据的width和height,处理相机预览流数据。
19```ts
20// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
21// component.byteBuffer为相机返回的预览流数据buffer
22
23receiver.readNextImage((err, nextImage: image.Image)=>{
24    nextImage.getComponent(image.ComponentType.JPEG, async(err, component: image.Component)=>{
25        let width = previewProfile.size.width
26        let height = previewProfile.size.height
27        // 相机预览流返回NV21格式
28        let pixelMap = await image.createPixelMap(component.byteBuffer, {
29            size:{height: height, width: width},
30            srcPixelFormat: image.PixelMapFormat.NV21,
31        })
32        ...
33    })
34})
35```
36
37变更后:
38应用开发者需要根据width,height,stride三个值,处理相机预览流数据。
39```ts
40// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
41// component.byteBuffer为相机返回的预览流数据buffer
42receiver.readNextImage((err, nextImage: image.Image)=>{
43    nextImage.getComponent(image.ComponentType.JPEG, async(err, component: image.Component)=>{
44        let width = previewProfile.size.width
45        let height = previewProfile.size.height
46        let stride = component.rowStride
47        // 相机预览流返回NV21格式
48        if (stride == width) {
49            let pixelMap = await image.createPixelMap(component.byteBuffer, {
50                size:{height: height, width: width},
51                srcPixelFormat: image.PixelMapFormat.NV21,
52            })
53        } else {
54            // 用法1.将component.byteBuffer中的数据去除掉stride,拷贝得到新的dstArr数据,传给其他不支持stride的接口处理。
55            const dstBufferSize = width * height * 1.5
56            const dstArr = new Uint8Array(dstBufferSize)
57            for (let j = 0; j < height * 1.5; j++) {
58                // component.byteBuffer的每行数据拷贝前width个字节到dstArr中
59                const srcBuf = new Uint8Array(component.byteBuffer, j*stride, width)
60                dstArr.set(srcBuf, j*width)
61            }
62            let pixelMap = await image.createPixelMap(dstArr.buffer, {
63                size:{height: height, width: width},
64                srcPixelFormat: image.PixelMapFormat.NV21,
65            })
66
67            // 用法2.如果仅想通过byteBuffer预览流数据创建pixelMap然后显示,可以根据stride*height创建pixelMap,然后调用crop方法裁剪掉多余的像素
68            let pixelMap = await image.createPixelMap(dstArr.buffer, {
69                size:{height: height, width: stride},
70                srcPixelFormat: image.PixelMapFormat.NV21,
71            })
72            pixelMap.cropSync({size:{width:width, height:height}, x:0, y:0})
73
74            // 用法3. 将byteBuffer预览流数据和stride信息一起传给支持stride的接口处理
75        }
76        ...
77    })
78})
79```
80
81**起始API Level**
82
83API 9
84
85**变更发生版本**
86
87从OpenHarmony 5.0.0.50 版本开始。
88
89**变更的接口/组件**
90@ohos.multimedia.image.d.ts下的接口:
91
92image.Component.rowStride接口
93
94**适配指导**
95
96变更:应用开发者需要根据width,height,stride三个值,处理相机预览流数据。
97
98```ts
99// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
100// component.byteBuffer为相机返回的预览流数据buffer
101receiver.readNextImage((err, nextImage: image.Image)=>{
102    nextImage.getComponent(image.ComponentType.JPEG, async(err, component: image.Component)=>{
103        let width = previewProfile.size.width
104        let height = previewProfile.size.height
105        let stride = component.rowStride
106        // 相机预览流返回NV21格式
107        if (stride == width) {
108            let pixelMap = await image.createPixelMap(component.byteBuffer, {
109                size:{height: height, width: width},
110                srcPixelFormat: image.PixelMapFormat.NV21,
111            })
112        } else {
113            // 用法1.将component.byteBuffer中的数据去除掉stride,拷贝得到新的dstArr数据,传给其他不支持stride的接口处理。
114            const dstBufferSize = width * height * 1.5
115            const dstArr = new Uint8Array(dstBufferSize)
116            for (let j = 0; j < height * 1.5; j++) {
117                // component.byteBuffer的每行数据拷贝前width个字节到dstArr中
118                const srcBuf = new Uint8Array(component.byteBuffer, j*stride, width)
119                dstArr.set(srcBuf, j*width)
120            }
121            let pixelMap = await image.createPixelMap(dstArr.buffer, {
122                size:{height: height, width: width},
123                srcPixelFormat: image.PixelMapFormat.NV21,
124            })
125
126            // 用法2.如果仅想通过byteBuffer预览流数据创建pixelMap然后显示,可以根据stride*height创建pixelMap,然后调用crop方法裁剪掉多余的像素
127            let pixelMap = await image.createPixelMap(dstArr.buffer, {
128                size:{height: height, width: stride},
129                srcPixelFormat: image.PixelMapFormat.NV21,
130            })
131            pixelMap.cropSync({size:{width:width, height:height}, x:0, y:0})
132
133            // 用法3. 将byteBuffer预览流数据和stride信息一起传给支持stride的接口处理
134        }
135        ...
136    })
137})
138```
139
140## cl.multimedia.2 OhosImageComponent接口中的rowStride返回值变更
141
142**访问级别**
143
144公开接口
145
146**变更原因**
147
148优化接口实现,当前返回值为图片的width,与接口定义不符,无法支撑开发者进行图片处理。
149
150**变更影响**
151
152该变更为兼容性变更。
153
154变更前:
155应用开发者根据预览流数据的width和height,处理相机预览流数据。
156```C++
157// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
158// component.byteBuffer为相机返回的预览流数据buffer
159int32_t ret;
160napi_value nextImage;
161ret = OH_Image_Receiver_ReadNextImage(imageReceiver_c, &nextImage);
162ImageNative* nextImage_native = OH_Image_InitImageNative(env, nextImage);
163OhosImageComponent imgComponent;
164ret = OH_Image_GetComponent(nextImage_native, jpegComponent, &imgComponent);
165
166uint8_t* srcBuffer = imgComponent.byteBuffer;
167OH_Pixelmap_InitializationOptions* options = nullptr;
168OH_PixelmapInitializationOptions_Create(&options);
169OH_PixelmapInitializationOptions_SetWidth(options, previewProfile.size.width);
170OH_PixelmapInitializationOptions_SetHeight(options, previewProfile.size.height);
171OH_PixelmapInitializationOptions_SetSrcPixelFormat(options, PIXEL_FORMAT_NV21);
172OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_NV21);
173OH_PixelmapNative* pixelmap = nullptr;
174OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
175```
176
177变更后:
178应用开发者需要根据width,height,stride三个值,处理相机预览流数据
179```C++
180// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
181// srcBuffer为相机返回的预览流数据buffer
182int32_t ret;
183napi_value nextImage;
184ret = OH_Image_Receiver_ReadNextImage(imageReceiver_c, &nextImage);
185ImageNative* nextImage_native = OH_Image_InitImageNative(env, nextImage);
186OhosImageComponent imgComponent;
187ret = OH_Image_GetComponent(nextImage_native, jpegComponent, &imgComponent);
188
189uint8_t* srcBuffer = imgComponent.byteBuffer;
190OH_Pixelmap_InitializationOptions* options = nullptr;
191OH_PixelmapInitializationOptions_Create(&options);
192OH_PixelmapInitializationOptions_SetWidth(options, previewProfile.size.width);
193OH_PixelmapInitializationOptions_SetHeight(options, previewProfile.size.height);
194OH_PixelmapInitializationOptions_SetSrcPixelFormat(options, PIXEL_FORMAT_NV21);
195OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_NV21);
196// 相机预览流返回NV21格式
197OH_PixelmapNative* pixelmap = nullptr;
198if (stride == width) {
199    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
200} else {
201    // 用法1.将srcBuffer中的数据去除掉stride,拷贝得到新的dstBuffer数据,传给其他不支持stride的接口处理。
202    size_t dstbufferSize = previewProfile.size.width * previewProfile.size.height * 1.5;
203    std::unique_ptr<uint8_t[]> dstBuffer = std::make_unique<uint8_t[]>(dstbufferSize);
204    uint8_t* dstPtr = dstBuffer.get();
205    for (int j = 0; j < previewProfile.size.height * 1.5; j++) {
206        memcpy_s(dstPtr, srcBuffer, previewProfile.size.width);
207        dstPtr += previewProfile.size.width;
208        srcBuffer += imgComponent.rowStride;
209    }
210    OH_PixelmapNative_CreatePixelmap(dstBuffer.get(), dstbufferSize, options, &pixelmap);
211
212    // 用法2.如果仅想通过srcBuffer预览流数据创建pixelMap然后显示,可以根据stride*height创建pixelMap,然后调用crop方法裁剪掉多余的像素
213    OH_PixelmapInitializationOptions_SetWidth(options, imgComponent.rowStride);
214    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
215    Image_Region region{0, 0, previewProfile.size.width, previewProfile.size.height};
216    OH_PixelmapNative_Crop(pixelmap, &region);
217
218    // 用法3. 将srcBuffer预览流数据和stride信息一起传给支持stride的接口处理
219}
220```
221
222**起始API Level**
223
224API 10
225
226**变更发生版本**
227
228从OpenHarmony 5.0.0.50 版本开始。
229
230**变更的接口/组件**
231<multimedia/image_framework/image_mdk.h>下的接口:
232
233OhosImageComponent接口中的rowStride属性
234
235**适配指导**
236
237应用开发者需要根据width,height,stride三个值,处理相机预览流数据。
238```C++
239// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
240// srcBuffer为相机返回的预览流数据buffer
241int32_t ret;
242napi_value nextImage;
243ret = OH_Image_Receiver_ReadNextImage(imageReceiver_c, &nextImage);
244ImageNative* nextImage_native = OH_Image_InitImageNative(env, nextImage);
245OhosImageComponent imgComponent;
246ret = OH_Image_GetComponent(nextImage_native, jpegComponent, &imgComponent);
247
248uint8_t* srcBuffer = imgComponent.byteBuffer;
249OH_Pixelmap_InitializationOptions* options = nullptr;
250OH_PixelmapInitializationOptions_Create(&options);
251OH_PixelmapInitializationOptions_SetWidth(options, previewProfile.size.width);
252OH_PixelmapInitializationOptions_SetHeight(options, previewProfile.size.height);
253OH_PixelmapInitializationOptions_SetSrcPixelFormat(options, PIXEL_FORMAT_NV21);
254OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_NV21);
255// 相机预览流返回NV21格式
256OH_PixelmapNative* pixelmap = nullptr;
257if (stride == width) {
258    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
259} else {
260    // 用法1.将srcBuffer中的数据去除掉stride,拷贝得到新的dstBuffer数据,传给其他不支持stride的接口处理。
261    size_t dstbufferSize = previewProfile.size.width * previewProfile.size.height * 1.5;
262    std::unique_ptr<uint8_t[]> dstBuffer = std::make_unique<uint8_t[]>(dstbufferSize);
263    uint8_t* dstPtr = dstBuffer.get();
264    for (int j = 0; j < previewProfile.size.height * 1.5; j++) {
265        memcpy_s(dstPtr, srcBuffer, previewProfile.size.width);
266        dstPtr += previewProfile.size.width;
267        srcBuffer += imgComponent.rowStride;
268    }
269    OH_PixelmapNative_CreatePixelmap(dstBuffer.get(), dstbufferSize, options, &pixelmap);
270
271    // 用法2.如果仅想通过srcBuffer预览流数据创建pixelMap然后显示,可以根据stride*height创建pixelMap,然后调用crop方法裁剪掉多余的像素
272    OH_PixelmapInitializationOptions_SetWidth(options, imgComponent.rowStride);
273    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
274    Image_Region region{0, 0, previewProfile.size.width, previewProfile.size.height};
275    OH_PixelmapNative_Crop(pixelmap, &region);
276
277    // 用法3. 将srcBuffer预览流数据和stride信息一起传给支持stride的接口处理
278}
279```
280
281## cl.multimedia.3 OH_ImageNative_GetRowStride接口返回值变更
282
283**访问级别**
284
285公开接口
286
287**变更原因**
288
289优化接口实现,当前返回值为图片的width,与接口定义不符,无法支撑开发者进行图片处理。
290
291**变更影响**
292
293该变更为兼容性变更。
294
295变更前:
296应用开发者根据预览流数据的width和height,处理相机预览流数据。
297```C++
298// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
299
300OH_ImageNative* image = nullptr;
301Image_ErrorCode errCode = OH_ImageReceiverNative_ReadNextImage(receiver, &image);
302size_t typeSize = 0;
303OH_ImageNative_GetComponentTypes(image, nullptr, &typeSize);
304uint32_t* types = new uint32_t[typeSize];
305OH_ImageNative_GetComponentTypes(image, &types, &typeSize);
306uint32_t component = types[0];
307OH_NativeBuffer* imageBuffer = nullptr;
308errCode = OH_ImageNative_GetByteBuffer(image, component, &imageBuffer);
309sizt_t bufferSize = 0;
310errCode = OH_ImageNative_GetByteBufferSize(image, component, &bufferSize);
311
312void* srcVir = nullptr;
313OH_NativeBuffer_Map(imageBuffer, &srcVir);
314OH_Pixelmap_InitializationOptions* options = nullptr;
315OH_PixelmapInitializationOptions_Create(&options);
316OH_PixelmapInitializationOptions_SetWidth(options, previewProfile.size.width);
317OH_PixelmapInitializationOptions_SetHeight(options, previewProfile.size.height);
318OH_PixelmapInitializationOptions_SetSrcPixelFormat(options, PIXEL_FORMAT_NV21);
319OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_NV21);
320OH_PixelmapNative* pixelmap = nullptr;
321OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcVir), bufferSize, options, &pixelmap);
322OH_NativeBuffer_Unmap(imageBuffer);
323```
324
325变更后:
326应用开发者需要根据width,height,stride三个值,处理相机预览流数据。
327```C++
328// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
329
330OH_ImageNative* image = nullptr;
331Image_ErrorCode errCode = OH_ImageReceiverNative_ReadNextImage(receiver, &image);
332size_t typeSize = 0;
333OH_ImageNative_GetComponentTypes(image, nullptr, &typeSize);
334uint32_t* types = new uint32_t[typeSize];
335OH_ImageNative_GetComponentTypes(image, &types, &typeSize);
336uint32_t component = types[0];
337OH_NativeBuffer* imageBuffer = nullptr;
338errCode = OH_ImageNative_GetByteBuffer(image, component, &imageBuffer);
339size_t bufferSize = 0;
340errCode = OH_ImageNative_GetByteBufferSize(image, component, &bufferSize);
341int32_t stride = 0;
342errCode = OH_ImageNative_GetRowStride(image, component, &stride);
343
344void* srcVir = nullptr;
345OH_NativeBuffer_Map(imageBuffer, &srcVir);
346OH_Pixelmap_InitializationOptions* options = nullptr;
347OH_PixelmapInitializationOptions_Create(&options);
348OH_PixelmapInitializationOptions_SetWidth(options, previewProfile.size.width);
349OH_PixelmapInitializationOptions_SetHeight(options, previewProfile.size.height);
350OH_PixelmapInitializationOptions_SetSrcPixelFormat(options, PIXEL_FORMAT_NV21);
351OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_NV21);
352OH_PixelmapNative* pixelmap = nullptr;
353if (stride == width) {
354    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcVir), bufferSize, options, &pixelmap);
355} else {
356    // 相机预览流返回NV21格式
357    // 用法1.将srcBuffer中的数据去除掉stride,拷贝得到新的dstBuffer数据,传给其他不支持stride的接口处理。
358    size_t dstbufferSize = previewProfile.size.width * previewProfile.size.height * 1.5;
359    std::unique_ptr<uint8_t[]> dstBuffer = std::make_unique<uint8_t[]>(dstbufferSize);
360    uint8_t* dstPtr = dstBuffer.get();
361    uint8_t* srcBuffer = static_cast<uint8_t*>(srcVir);
362    for (int j = 0; j < previewProfile.size.height * 1.5; j++) {
363        memcpy_s(dstPtr, srcBuffer, previewProfile.size.width);
364        dstPtr += previewProfile.size.width;
365        srcBuffer += imgComponent.rowStride;
366    }
367    OH_PixelmapNative_CreatePixelmap(dstBuffer.get(), dstbufferSize, options, &pixelmap);
368
369    // 用法2.如果仅想通过srcBuffer预览流数据创建pixelMap然后显示,可以根据stride*height创建pixelMap,然后调用crop方法裁剪掉多余的像素
370    OH_PixelmapInitializationOptions_SetWidth(options, imgComponent.rowStride);
371    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
372    Image_Region region{0, 0, previewProfile.size.width, previewProfile.size.height};
373    OH_PixelmapNative_Crop(pixelmap, &region);
374
375    // 用法3. 将srcBuffer预览流数据和stride信息一起传给支持stride的接口处理
376}
377OH_NativeBuffer_Unmap(imageBuffer);
378```
379
380**起始API Level**
381
382API 12
383
384**变更发生版本**
385
386从OpenHarmony 5.0.0.50 版本开始。
387
388**变更的接口/组件**
389<multimedia/image_framework/image/image_native.h>下的接口:
390
391OH_ImageNative_GetRowStride接口
392
393**适配指导**
394
395变更:应用开发者需要根据width,height,stride三个值,处理相机预览流数据。
396
397```c++
398// previewProfile为应用选中的某一个相机分辨率所对应的宽高,比如1080 * 1080
399
400OH_ImageNative* image = nullptr;
401Image_ErrorCode errCode = OH_ImageReceiverNative_ReadNextImage(receiver, &image);
402size_t typeSize = 0;
403OH_ImageNative_GetComponentTypes(image, nullptr, &typeSize);
404uint32_t* types = new uint32_t[typeSize];
405OH_ImageNative_GetComponentTypes(image, &types, &typeSize);
406uint32_t component = types[0];
407OH_NativeBuffer* imageBuffer = nullptr;
408errCode = OH_ImageNative_GetByteBuffer(image, component, &imageBuffer);
409size_t bufferSize = 0;
410errCode = OH_ImageNative_GetByteBufferSize(image, component, &bufferSize);
411int32_t stride = 0;
412errCode = OH_ImageNative_GetRowStride(image, component, &stride);
413
414void* srcVir = nullptr;
415OH_NativeBuffer_Map(imageBuffer, &srcVir);
416OH_Pixelmap_InitializationOptions* options = nullptr;
417OH_PixelmapInitializationOptions_Create(&options);
418OH_PixelmapInitializationOptions_SetWidth(options, previewProfile.size.width);
419OH_PixelmapInitializationOptions_SetHeight(options, previewProfile.size.height);
420OH_PixelmapInitializationOptions_SetSrcPixelFormat(options, PIXEL_FORMAT_NV21);
421OH_PixelmapInitializationOptions_SetPixelFormat(options, PIXEL_FORMAT_NV21);
422OH_PixelmapNative* pixelmap = nullptr;
423if (stride == width) {
424    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcVir), bufferSize, options, &pixelmap);
425} else {
426    // 相机预览流返回NV21格式
427    // 用法1.将srcBuffer中的数据去除掉stride,拷贝得到新的dstBuffer数据,传给其他不支持stride的接口处理。
428    size_t dstbufferSize = previewProfile.size.width * previewProfile.size.height * 1.5;
429    std::unique_ptr<uint8_t[]> dstBuffer = std::make_unique<uint8_t[]>(dstbufferSize);
430    uint8_t* dstPtr = dstBuffer.get();
431    uint8_t* srcBuffer = static_cast<uint8_t*>(srcVir);
432    for (int j = 0; j < previewProfile.size.height * 1.5; j++) {
433        memcpy_s(dstPtr, srcBuffer, previewProfile.size.width);
434        dstPtr += previewProfile.size.width;
435        srcBuffer += imgComponent.rowStride;
436    }
437    OH_PixelmapNative_CreatePixelmap(dstBuffer.get(), dstbufferSize, options, &pixelmap);
438
439    // 用法2.如果仅想通过srcBuffer预览流数据创建pixelMap然后显示,可以根据stride*height创建pixelMap,然后调用crop方法裁剪掉多余的像素
440    OH_PixelmapInitializationOptions_SetWidth(options, imgComponent.rowStride);
441    OH_PixelmapNative_CreatePixelmap(static_cast<unsigned char*>(srcBuffer), imgComponent.size, options, &pixelmap);
442    Image_Region region{0, 0, previewProfile.size.width, previewProfile.size.height};
443    OH_PixelmapNative_Crop(pixelmap, &region);
444
445    // 用法3. 将srcBuffer预览流数据和stride信息一起传给支持stride的接口处理
446}
447OH_NativeBuffer_Unmap(imageBuffer);
448```