鸿蒙(API 12 Beta3版)【使用Image完成图片接收器】图片开发指导依赖JS对象

news2024/9/23 16:23:19

图像接收类,用于获取组件surface id,接收最新的图片和读取下一张图片,以及释放ImageReceiver实例。

开发步骤

添加依赖

在进行应用开发之前,开发者需要打开native工程的src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加libace_napi.z.so,libimage_ndk.z.so,libimage_receiver_ndk.z.so,libnative_image.so 以及日志依赖libhilog_ndk.z.so。

target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libimage_ndk.z.so libimage_receiver_ndk.z.so libnative_image.so)

添加接口映射

打开src/main/cpp/hello.cpp文件,在Init函数中添加接口映射如下:

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "createFromReceiver", nullptr, createFromReceiver, nullptr, nullptr, nullptr, napi_default, nullptr },
    };

    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

添加权限申请

此处通过camera图片获取输入数据,需要申请权限ohos.permission.CAMERA,申请方式请参考[向用户申请授权]

JS侧调用

  1. 打开src\main\cpp\types\libentry\index.d.ts(其中libentry根据工程名生成),导入如下引用文件:
import { image } from '@kit.ImageKit';

export const createFromReceiver: (a: image.ImageReceiver) => image.Image;
  1. 打开src\main\ets\pages\index.ets,导入"libentry.so(根据工程名生成)",调用Native接口,传入JS的资源对象。示例如下:
import testNapi from 'libentry.so'
import { image } from '@kit.ImageKit';
import { abilityAccessCtrl } from '@kit.AbilityKit';
import { camera } from '@kit.CameraKit';

@Entry
@Component
struct Index {
  private receiver: image.ImageReceiver | undefined = undefined;
  func (){
     let context = getContext()
     abilityAccessCtrl.createAtManager().requestPermissionsFromUser(context,['ohos.permission.CAMERA']).then(async () => {
        let cameraManager = await camera.getCameraManager(context);
        // 获取支持的相机设备对象
        let cameraDevices: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
        if (cameraDevices.length <= 0) {
        return;
        }
        // 获取对应相机设备的profiles
        let profiles: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraDevices[0])
        let previewProfiles: Array<camera.Profile> = profiles.previewProfiles;
        if (previewProfiles.length <= 0) {
        return;
        }
        let profileObj = previewProfiles[0];
        this.receiver = image.createImageReceiver(profileObj.size.width, profileObj.size.height, image.ImageFormat.JPEG, 8);
        let receiverSurfaceId: string = await this.receiver.getReceivingSurfaceId();
        // 创建预览流输出对象
        let previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(profileObj,receiverSurfaceId);
        let cameraInput : camera.CameraInput = cameraManager.createCameraInput(cameraDevices[0]);
        // 打开相机
        await cameraInput.open();
        // 会话流程
        let captureSession : camera.CaptureSession = cameraManager.createCaptureSession();
        // 配置会话
        captureSession.beginConfig();
        // 把cameraInput加入到会话
        captureSession.addInput(cameraInput);
        // 把预览流加入到会话
        captureSession.addOutput(previewOutput);
        // 提交配置信息
        await captureSession.commitConfig();
        // 会话开始
        await captureSession.start();

        this.receiver.on('imageArrival', () => {
           let img : image.Image = testNapi.createFromReceiver(this.receiver);
           img.release();
        })

     });
  }

  build() {
     Row() {
        Column() {
        Button("start")
           .width(100)
           .height(100)
           .onClick(() => {
              console.log("button click in");
              if (this.receiver == undefined) {
                 this.func();
              }
           })
        }
        .width('100%')
     }
     .height('100%')
  }
}

Native接口调用

在hello.cpp文件中获取JS的资源对象,并转为Native的资源对象,即可调用Native接口,调用方式示例代码如下:

添加引用文件

   #include <multimedia/image_framework/image_mdk.h>
   #include <multimedia/image_framework/image_receiver_mdk.h>
   #include <malloc.h>
   #include <hilog/log.h>

   static napi_value createFromReceiver(napi_env env, napi_callback_info info)
   {
      size_t argc = 1;
      napi_value args[2] = {nullptr};
      napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
      napi_valuetype valuetype0;
      napi_typeof(env, args[0], &valuetype0);
      napi_ref reference;
      napi_create_reference(env, args[0], 1 ,&reference);
      napi_value imgReceiver_js;
      napi_get_reference_value(env, reference, &imgReceiver_js);
      
      ImageReceiverNative * imgReceiver_c = OH_Image_Receiver_InitImageReceiverNative(env, imgReceiver_js);

      int32_t capacity;
      OH_Image_Receiver_GetCapacity(imgReceiver_c, &capacity);
      OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "capacity: %{public}d", capacity);
      int32_t format;
      OH_Image_Receiver_GetFormat(imgReceiver_c, &format);
      OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "format: %{public}d", format);
      char * surfaceId = static_cast<char *>(malloc(sizeof(char)));
      OH_Image_Receiver_GetReceivingSurfaceId(imgReceiver_c, surfaceId, sizeof(char));
      OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "surfaceId: %{public}c", surfaceId[0]);
      OhosImageSize size;
      OH_Image_Receiver_GetSize(imgReceiver_c, &size);
      OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "OH_Image_Receiver_GetSize  width: %{public}d, height:%{public}d", size.width, size.height);
      
      int32_t ret;
      napi_value nextImage;
      // 或调用 OH_Image_Receiver_ReadNextImage(imgReceiver_c, &nextImage);
      ret = OH_Image_Receiver_ReadLatestImage(imgReceiver_c, &nextImage);
      
      ImageNative * nextImage_native = OH_Image_InitImageNative(env, nextImage);

      OhosImageSize imageSize;
      OH_Image_Size(nextImage_native, &imageSize);
      OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "OH_Image_Size  width: %{public}d, height:%{public}d", imageSize.width, imageSize.height);

      OhosImageComponent imgComponent;
      ret = OH_Image_GetComponent(nextImage_native, 4, &imgComponent); // 4=jpeg
      
      uint8_t *img_buffer = imgComponent.byteBuffer;
      
      ret = OH_Image_Release(nextImage_native);
      ret = OH_Image_Receiver_Release(imgReceiver_c);
      return nextImage;
   }

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿
1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2068330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Qt】Qt系统 | Qt事件| 鼠标事件

文章目录 鼠标事件鼠标点击事件鼠标释放事件鼠标双击事件鼠标移动事件 滚轮事件 在 Qt 中&#xff0c;鼠标事件是用 QMouseEvent 实现的。当在窗口中按下鼠标或者移动鼠标时&#xff0c;都会产生鼠标事件 鼠标事件 鼠标点击事件 鼠标按下时通过 虚函数 mousePressEvent() 来…

系统编程—进程

一、进程的概念 1.程序与进程的区别 程序:编译后产生的&#xff0c;格式为ELF的&#xff0c;存储于硬盘的文件。可以通过 readelf -s [文件名] 查看文件信息 …

使用OpenRewrite升级SpringBoot项目

使用OpenRewrite升级SpringBoot项目 什么是OpenRewrite? OpenRewrite是一个强大的开源自动化源代码重构工具,专为大规模代码库设计。它的核心理念是通过程序化的方式来改变源代码,而不是依赖于手动编辑或简单的查找替换。 OpenRewrite的主要特点和优势包括: 自动重构: Open…

Unity动画模块 之 Animator中一些常见参数

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 我发现我忘了写Animator了&#xff0c;正好有些不常用的参数还没怎么认识,笔记来源于唐老狮 1.状态窗口参数 2.连线参数…

Lesson05--C/C++内存管理

1. C/C内存分布 2. C语言中动态内存管理方式 3. C中动态内存管理 4. operator new与operator delete函数 5. new和delete的实现原理 6. 定位new表达式(placement-new) 7. 常见面试题 1. C/C内存分布 为了方便管理内存被分为了以上的区域 我们来看下面的一段代码和相关问题 …

数据结构(邓俊辉)学习笔记】优先级队列 08——左式堆:结构

文章目录 1. 第一印象2. 堆之合并3. 奇中求正4. NPL5. 左倾性6. 左展右敛 1. 第一印象 在学习过常规的完全二叉堆之后&#xff0c;我们再来学习优先级队列的另一变种&#xff0c;也就是左式堆。所谓的左式堆&#xff0c;也就是在拓扑形态上更加倾向于向左侧倾斜的一种堆&#…

Vue3 项目结构

1.main.ts 2.简单写一个src下的结构 App.vue 根组件 <template><div class"app"><!-- html --><h1>你好啊!</h1></div> </template><script lang"ts"> //js 或 tsexport default {name:App,//组件名 }…

MySQL数据库锁机制(全面讲解)

目录 1、全局锁 1.1、全局锁使用语法 1.2、备份数据库&#xff08;不使用全局锁&#xff09; 2、表锁 2.1、读写锁 读锁 写锁 2.2、元数据锁&#xff08;meta data lock MDL&#xff09; 2.3、意向锁 3、行锁 3.1、共享锁和排他锁 共享锁&#xff08;S锁&#xff…

原来marker还能这么玩

在Web GIS开发中&#xff0c;Marker&#xff08;标记&#xff09;是一个基本但强大的工具。今天&#xff0c;我们将探讨如何通过不同的API调用&#xff0c;将Marker玩出新花样&#xff0c;让地图更加生动有趣。 最基础的Marker用法是在地图上标记一个具体位置。我们可以通过“m…

【Unity3D小技巧】Unity3D中实现对InputField的自定义输入限制实例

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群&#xff1a;398291828 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 InputField是UGUI的文本输入框&#xff0c;自带的…

粘包,Telnet,SSH,Wireshark

一&#xff0c;粘包 原因&#xff1a;tcp为流式套接字&#xff0c;数据与数据间没有边界&#xff0c;导致多次数据粘到一起。 解决&#xff1a; 1.规定一些数据间的间隔符&#xff0c;"\aa","\r\n"; 2.可以指定要发送对象的数据长度。 3.自己将数据打包。 …

力扣:有效的数独

文章目录 需求分析结尾 需求 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08…

2024年最新最全的【大模型学习路线规划】从零基础入门到精通!

2024年最新最全的大模型学习路线规划&#xff0c;对于零基础入门到精通的学习者来说&#xff0c;可以遵循以下阶段进行&#xff1a; 文章目录 一、基础准备阶段数学基础&#xff1a;编程语言&#xff1a;深度学习基础&#xff1a; 二、核心技术学习阶段Transformer模型&#xf…

第2章-04-Request Header与Response Header

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年CSDN全站百大博主。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:Web爬虫入门与实战精讲,后续完整更新内容如下。 文章…

TortoiseGit使用教程

系列文章目录 文章目录 系列文章目录前言一、TortoiseGit下载安装二、使用步骤1.创建库1.需要上传的文件&#xff1a;不需要上传的文件&#xff1a; 2.拉取代码 前言 以前都是用svn&#xff0c;现在改用git Git是目前世界上最先进的分布式版本控制系统&#xff08;没有之一&am…

IO进程day01(标准IO、缓存区)

目录 【1】标准IO 1》概念&#xff1a; 2》特点 【2】缓存区 1》全缓存&#xff1a;和文件相关 2》行缓存&#xff1a;和终端有关 3》不缓存&#xff1a;也就是没有缓存区&#xff0c;标准错误。 【1】标准IO 1》概念&#xff1a; 标准IO&#xff1a; 是在C库中定义的一…

Linux入门——10 信号

1.信号 1.信号------信号量&#xff08;两者没有任何关系&#xff09; 2.信号讲什么----->整个信号的生命周期 信号的产生-----信号的保存------信号的处理 之前的kill命令&#xff0c;用的就是信号。 kill -l查看系统支持的信号 名字本身就是宏&#xff0c;其实就是编…

java—1 封装

目录 一、零碎内容 一、输入、输出 二、idea项目结构 三、Java标识符的命名规范&#xff08;约定俗成&#xff09; 四. 方法和函数 二、快捷键 三、数组 1. 声明数组 2. 静态初始化 3. 数组动态初始化 4. 声明和初始化一起完成 5. 数组地址 四、面向对象编程 1. …

进程函数练习

创建子父进程&#xff0c;子进程将1.txt内容拷贝到2.txt中&#xff0c;父进程将3.txt内容拷贝到4.txt中。 #include <myhead.h>int main(int argc, const char *argv[]) {pid_t ID;ID fork();if(ID>0)//父进程{printf("父进程ID:%d\n",ID);int fd open(&…

C HTML格式解析与生成

cmake报错替换 if(NOT MyHTML_BUILD_WITHOUT_THREADS OR NOT MyCORE_BUILD_WITHOUT_THREADS) set(CMAKE_THREAD_PREFER_PTHREAD 1) if (WIN32) set(CMAKE_USE_WIN32_THREADS_INIT ON) set(CMAKE_THREAD_PREFER_PTHREADS TRUE) set(THREADS_PR…