news 2026/7/7 20:20:33

鸿蒙开发-如何将C++侧接收的PixelMap转换成cv::mat格式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙开发-如何将C++侧接收的PixelMap转换成cv::mat格式

目录

  • 1. 解决措施
  • 2. 示例代码
  • 3. 将arraybuffer转换成cv::mat
  • 4. 使用OH_PixelMap_AccessPixels获取PixelMap的内存地址,将这个内存地址中的数据转换为cv::mat的

1. 解决措施

将PixelMap转换成cv::mat有两种方法:

  • 将PixelMap的arraybuffer转换成cv::mat。
  • 使用OH_PixelMap_AccessPixels获取PixelMap的内存地址,将这个内存地址中的数据转换为cv::mat。

上述两种方法都需确保PixelMap的格式与OpenCV中Mat的格式一致,否则会导致色彩偏差。

2. 示例代码

importcPixelMapToMatfrom'libcpixelmaptomat.so';import{BusinessError}from'@kit.BasicServicesKit';import{image}from'@kit.ImageKit';@Entry @Component struct Index{@State pixelMap:image.PixelMap|undefined=undefinedasyncarrayBufferToMat(){if(this.pixelMap==undefined||this.pixelMap){letcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;letresourceManager=context.resourceManagerletimageArray=awaitresourceManager.getMediaContent($r('app.media.sample10'));letpixelBuffer=newUint8Array(imageArray).bufferasObjectasArrayBuffer console.info("pixelBuffer length: "+pixelBuffer.byteLength);letimageResource=image.createImageSource(pixelBuffer);letopts:image.DecodingOptions={editable:true,desiredPixelFormat:image.PixelMapFormat.RGBA_8888}this.pixelMap=awaitimageResource.createPixelMap(opts);}constreadBuffer:ArrayBuffer=newArrayBuffer(this.pixelMap.getPixelBytesNumber());// Obtain the array buffer of the pixelmapconsole.info("readBuffer length: "+readBuffer.byteLength);this.pixelMap.readPixelsToBuffer(readBuffer).then(()=>{console.info("No Error!")}).catch((err:BusinessError)=>{console.error("Error! "+err.message)})constdir=getContext(this).filesDir;console.info('save path: '+dir);cPixelMapToMat.arrayBufferToMat(this.pixelMap,readBuffer,dir);}asyncaccessToMat(){if(this.pixelMap==undefined||this.pixelMap){letresourceManager=getContext(this).resourceManagerletimageArray=awaitresourceManager.getMediaContent($r('app.media.sample14'));letpixelBuffer=newUint8Array(imageArray).bufferasObjectasArrayBuffer console.info("pixelBuffer length: "+pixelBuffer.byteLength);letimageResource=image.createImageSource(pixelBuffer);letopts:image.DecodingOptions={editable:true,desiredPixelFormat:image.PixelMapFormat.RGBA_8888}this.pixelMap=awaitimageResource.createPixelMap(opts);}constdir=getContext(this).filesDir;console.info('save path: '+dir);cPixelMapToMat.accessToMat(this.pixelMap,dir);}build(){Row(){Column(){Image(this.pixelMap).width(200).height(200)Button('ArrayBufferToMat').onClick(()=>{this.arrayBufferToMat();})Button('AccessToMat').onClick(()=>{this.accessToMat();})}.width('100%')}.height('100%')}}

3. 将arraybuffer转换成cv::mat

#include"napi/native_api.h"#include<multimedia/image_framework/image_mdk.h>#include<multimedia/image_framework/image_mdk_common.h>#include<multimedia/image_framework/image_pixel_map_mdk.h>#include<multimedia/image_framework/image_pixel_map_napi.h>#include"hilog/log.h"#include<opencv2/opencv.hpp>#include<bits/alltypes.h>staticnapi_valueArrayBufferToMat(napi_env env,napi_callback_info info){size_t argc=3;napi_value args[3]={nullptr};napi_get_cb_info(env,info,&argc,args,nullptr,nullptr);napi_value error;napi_create_int32(env,-1,&error);// Initialize PixelMap object dataNativePixelMap*native=OH_PixelMap_InitNativePixelMap(env,args[0]);if(native==nullptr){returnerror;}// Obtaining Image InformationstructOhosPixelMapInfospixelMapInfos;if(OH_PixelMap_GetImageInfo(native,&pixelMapInfos)!=IMAGE_RESULT_SUCCESS){OH_LOG_Print(LOG_APP,LOG_ERROR,0xFF00,"Test","Pure : -1");returnerror;}// Obtains the buffernapi_value buffer=args[1];napi_valuetype valueType;napi_typeof(env,buffer,&valueType);if(valueType==napi_object){boolisArrayBuffer=false;napi_is_arraybuffer(env,buffer,&isArrayBuffer);if(!isArrayBuffer){napi_throw_error(env,"EINVAL","Error");}}void*data=nullptr;size_t byteLength=0;napi_get_arraybuffer_info(env,buffer,&data,&byteLength);int32_t*saveBuffer=(int32_t*)(data);// Convert to Matcv::MatoriginMat(pixelMapInfos.height,pixelMapInfos.width,CV_8UC4,saveBuffer);if(!originMat.data){OH_LOG_Print(LOG_APP,LOG_ERROR,0xFF00,"Read Image","Pure : -1");returnerror;}// openCV defaults to BGRA or BGR. If the pixelmap is not created in one of these formats, a format conversion is requiredcv::Mat saveMat;cv::cvtColor(originMat,saveMat,cv::COLOR_BGRA2RGBA);charpathArray[1024];size_t length;napi_get_value_string_utf8(env,args[2],pathArray,1024,&length);std::stringpath(pathArray);path+="/buffer.jpg";if(!cv::imwrite(path,saveMat)){OH_LOG_Print(LOG_APP,LOG_ERROR,0xFF00,"Write Image","Pure : -1");returnerror;}napi_value res;napi_create_int32(env,1,&res);returnres;}

4. 使用OH_PixelMap_AccessPixels获取PixelMap的内存地址,将这个内存地址中的数据转换为cv::mat的

staticnapi_valueAccessToMat(napi_env env,napi_callback_info info){size_t argc=2;napi_value args[2]={nullptr};napi_get_cb_info(env,info,&argc,args,nullptr,nullptr);napi_value error;napi_create_int32(env,-1,&error);NativePixelMap*native=OH_PixelMap_InitNativePixelMap(env,args[0]);if(native==nullptr){returnerror;}structOhosPixelMapInfospixelMapInfos;if(OH_PixelMap_GetImageInfo(native,&pixelMapInfos)!=IMAGE_RESULT_SUCCESS){OH_LOG_Print(LOG_APP,LOG_ERROR,0xFF00,"Test","Pure : -1");returnerror;}void*pixel;// Obtain the memory address of the NativePixelMap object and lock the memoryOH_PixelMap_AccessPixels(native,&pixel);// Convert to Mat, pay attention to alignment, so rowSize needs to be passed incv::MatoriginMat(pixelMapInfos.height,pixelMapInfos.width,CV_8UC4,pixel,pixelMapInfos.rowSize);if(!originMat.data){OH_LOG_Print(LOG_APP,LOG_ERROR,0xFF00,"Read Image","Pure : -1");returnerror;}// openCV defaults to BGRA or BGR. If the pixelmap is not created in one of these formats, a format conversion is requiredcv::Mat saveMat;cv::cvtColor(originMat,saveMat,cv::COLOR_BGRA2RGBA);charpathArray[1024];size_t length;napi_get_value_string_utf8(env,args[1],pathArray,1024,&length);std::stringpath(pathArray);path+="/access.jpg";if(!cv::imwrite(path,saveMat)){OH_LOG_Print(LOG_APP,LOG_ERROR,0xFF00,"Write Image","Pure : -1");returnerror;}napi_value res;napi_create_int32(env,1,&res);returnres;}

在HarmonyOS开发中,针对图库支持硬解码的操作,需要指定图像的内存空间大小。OH_PixelMap_AccessPixels() 获取图片的内存地址并锁定该内存。实际图像的大小需要按 lineStride 对齐。因此,在构造成 mat 时,需指定 lineStride 对齐。lineStride即 rowSize。可以使用 OH_GetImageInfo 获取 imageInfo,其中包含 width、height 和 rowSize 等信息。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 11:02:17

YOLOv8深度解析:为什么它成为大模型微调新宠?

YOLOv8深度解析&#xff1a;为什么它成为大模型微调新宠&#xff1f; 在智能摄像头遍布工厂车间、自动驾驶车辆穿梭于城市街道的今天&#xff0c;一个共同的技术挑战摆在面前&#xff1a;如何让机器“看”得又快又准&#xff1f;尤其是在边缘设备资源受限、云端推理成本敏感的背…

作者头像 李华
网站建设 2026/7/7 18:35:21

Qwen-Image-Edit-2509本地部署与智能图像编辑指南

Qwen-Image-Edit-2509本地部署与智能图像编辑指南 你有没有经历过这样的场景&#xff1a;市场部临时通知&#xff0c;“所有产品图的LOGO必须今晚全部换成新版&#xff0c;明天一早上线”&#xff0c;而设计师早已下班&#xff1f;又或者&#xff0c;运营需要为春节、情人节、6…

作者头像 李华
网站建设 2026/7/7 19:27:05

利用AI agents追踪内部交易:洞察公司内部信心

利用AI agents追踪内部交易&#xff1a;洞察公司内部信心关键词&#xff1a;AI agents、内部交易追踪、公司内部信心、数据分析、金融监管摘要&#xff1a;本文聚焦于利用AI agents追踪内部交易以洞察公司内部信心这一前沿话题。首先介绍了相关背景&#xff0c;包括研究目的、预…

作者头像 李华
网站建设 2026/7/7 19:37:49

Seed-Coder-8B-Base如何生成OpenAPI实现代码

Seed-Coder-8B-Base如何生成OpenAPI实现代码 在现代软件开发中&#xff0c;一个常见的场景是&#xff1a;前端团队正焦急地等待后端提供用户管理接口的联调地址&#xff0c;而后端工程师却还在手敲 UserController.java 里的第17个 GetMapping——明明 OpenAPI 文档早就写好了&…

作者头像 李华
网站建设 2026/7/7 10:12:07

LobeChat能否驾驶无人机?空中任务指挥官

LobeChat能否驾驶无人机&#xff1f;空中任务指挥官 在一片广袤的农田上&#xff0c;一位农民掏出手机&#xff0c;轻声说&#xff1a;“让无人机去东边那块地看看小麦有没有锈病。” 几秒钟后&#xff0c;远处的多旋翼无人机自动启动、升空、飞向指定区域&#xff0c;完成航拍…

作者头像 李华
网站建设 2026/7/7 9:17:23

腾讯混元开源HunyuanVideo-Foley:AI视频音效生成新突破

腾讯混元开源HunyuanVideo-Foley&#xff1a;AI视频音效生成新突破 在短视频日活破十亿、AIGC内容井喷的今天&#xff0c;我们似乎已经习惯了“一键生成画面”、“AI配音朗读”&#xff0c;但当你点开一段由AI生成的视频时&#xff0c;是否总觉得少了点什么&#xff1f;—— 没…

作者头像 李华