news 2026/5/11 7:51:08

鸿蒙开发-如何将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/4/30 23:21:07

四天学会一本书的厦门服务机构是哪家

四天学会一本书&#xff1a;厦门诺辰教育如何助力高效学习在快节奏的现代生活中&#xff0c;高效学习已成为许多人追求的目标。尤其是在知识更新迅速的时代&#xff0c;如何在短时间内掌握一本书的核心内容变得尤为重要。厦门诺辰教育作为一家专注于高效学习方法培训的服务机构…

作者头像 李华
网站建设 2026/5/8 17:44:01

AI在HR数字化中的应用:简历筛选与人才匹配的技术实现

摘要&#xff1a;在HR数字化转型进程中&#xff0c;简历筛选与人才匹配是招聘全流程的核心痛点。传统人工筛选模式效率低下、主观性强&#xff0c;难以适应大规模招聘需求。AI技术的融入为该场景提供了高效解决方案&#xff0c;通过OCR识别、自然语言处理&#xff08;NLP&#…

作者头像 李华
网站建设 2026/5/11 5:32:10

anything-llm Docker本地部署与源码问答指南

anything-llm Docker本地部署与源码问答指南 在现代软件开发中&#xff0c;面对动辄数百万行的代码库&#xff0c;如何快速理解系统架构、定位关键逻辑、掌握模块交互&#xff0c;已成为开发者日常效率的核心瓶颈。尤其像 Android AOSP、Linux 内核这类大型项目&#xff0c;仅…

作者头像 李华
网站建设 2026/5/3 21:15:57

LobeChat Docker镜像使用技巧:环境变量配置大全

LobeChat Docker镜像使用技巧&#xff1a;环境变量配置大全 在构建现代 AI 聊天应用的实践中&#xff0c;一个常见痛点是&#xff1a;如何快速、安全地将前端界面与后端大模型服务对接&#xff0c;同时兼顾部署灵活性和访问控制&#xff1f;开源项目 LobeChat 正是为解决这一问…

作者头像 李华
网站建设 2026/5/10 11:17:35

语音合成新突破:GPT-SoVITS实现跨语言TTS只需1分钟音频

语音合成新突破&#xff1a;GPT-SoVITS实现跨语言TTS只需1分钟音频 在内容创作日益个性化的今天&#xff0c;越来越多的自媒体人、教育工作者甚至普通用户开始思考一个问题&#xff1a;能不能让AI用我的声音说话&#xff1f; 过去&#xff0c;这听起来像是科幻电影的情节。传统…

作者头像 李华
网站建设 2026/5/2 1:22:08

Java矩阵乘法

任务描述 本关任务&#xff1a;编写一个程序&#xff0c;输入两个矩阵输出矩阵乘的结果。矩阵乘法 矩阵相乘最重要的方法是一般矩阵乘积。它只有在第一个矩阵的列数&#xff08; column &#xff09;和第二个矩阵的行数&#xff08; row &#xff09;相同时才有意义。 矩阵乘法…

作者头像 李华