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