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, ®ion); 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, ®ion); 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, ®ion); 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, ®ion); 444e41f4b71Sopenharmony_ci 445e41f4b71Sopenharmony_ci // 用法3. 将srcBuffer预览流数据和stride信息一起传给支持stride的接口处理 446e41f4b71Sopenharmony_ci} 447e41f4b71Sopenharmony_ciOH_NativeBuffer_Unmap(imageBuffer); 448e41f4b71Sopenharmony_ci```