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