news 2026/1/17 7:04:34

鸿蒙开发-如何将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/1/16 15:08:43

力扣701 二叉搜索树中的插入操作 java实现

701.二叉搜索树中的插入操作给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。注意&#xff0c;可能…

作者头像 李华
网站建设 2026/1/16 12:27:55

TensorFlow-GPU安装全指南:版本匹配与实操避坑

TensorFlow-GPU 安装实战指南&#xff1a;绕过版本陷阱&#xff0c;一次成功 在深度学习的世界里&#xff0c;本地 GPU 环境就像炼丹炉——谁不想亲手点燃那团算力之火&#xff1f;可现实往往是&#xff1a;折腾三天三夜&#xff0c;连 tf.device(/GPU) 都跑不通。报错信息五花…

作者头像 李华
网站建设 2026/1/16 13:46:26

LobeChat能否实现AI猜谜游戏?娱乐化交互场景开发

LobeChat能否实现AI猜谜游戏&#xff1f;娱乐化交互场景开发 在智能对话系统日益普及的今天&#xff0c;用户早已不满足于“问一句答一句”的机械互动。他们期待的是更自然、更有趣、甚至带点“人情味”的交流体验——比如和一个会出谜题、能引导思考、还会适时鼓励你的AI玩一场…

作者头像 李华
网站建设 2026/1/16 18:57:30

和鲸科技创始人CEO 范向伟受邀赴港亮相 AI 赋能・科技自立 —— 中小企业创新与机遇高峰论坛并做主题演讲

本文内容节选自&#xff1a;香港中小上市公司协会&#xff0c;内容略有删改2025年12月5日&#xff0c;由香港中小上市公司协会&#xff08;下文简称「协会」&#xff09;联同深圳市金融商会主办的「AI赋能・科技自立——中小企业创新与机遇高峰论坛」&#xff0c;于香港四季酒店…

作者头像 李华
网站建设 2026/1/16 20:27:06

Cypress 入门与优势分析:前端自动化测试的新利器

近两年&#xff0c;前端自动化测试在各大互联网团队中越来越火&#xff0c;而 Cypress 作为新一代前端自动化框架&#xff0c;成为开发和 QA 团队热议的对象。 本文将从前端测试痛点、核心功能、Cypress 流程和对比分析带你快速了解它的价值。 1. 前端自动化测试痛点 调试困难…

作者头像 李华
网站建设 2026/1/15 8:01:08

鸿蒙高性能图形绘制

说明 HarmonyOs ArkGraphics 2D&#xff08;方舟2D图形服务 &#xff09;提供的绘制引擎&#xff0c;如果在 ArkUI 侧绘制&#xff0c;对绘制性能有高要求的话&#xff0c;那就直接放弃&#xff0c;转Native绘制配合 GPU 后端渲染。&#xff08;想到这儿我浑身难受&#xff09…

作者头像 李华