OpenHarmony3.2 beta4上照相机的使用之1--开启照相机预览画面

2023-11-02

随着OpenHarmony的版本更新,在3.2上已经提供了非常丰富的API来调用照相机。此处讲解的是原生的使用相机的流程,并发像Android普通应用开发一样通过一个intent直接调用系统相机应用进行拍照,根据原生的调用相机的API可以让大家自己定义功能更加丰富的相机应用。

这里为何我特意强调是OpenHarmony3.2 beta4,因为我发现即使同为3.2版本,beta4上的Camera相关的api和beta2版本差距都非常大,于是选取了当前最新的版本进行讲解。

既然使用相机,那么第一步是先想办法把相机点亮,即能通过摄像头看到预览画面,后面才是拍照、录像、分布式拍照等功能实现。

关于sdk的问题

目前在OpenHarmony3.2上调用相机,需要使用ohos-full-sdk,而非大家下载DevEco Studio所带的sdk,那个sdk被称作为public sdk。关于sdk的替换办法可以参考官方文档“ full-SDK替换指南”,我这里不过多赘述。

此处核心要注意的一点是,目前我3.2 beta4上用的sdk对应的版本号为3.2.9.4

而目前官方文档上写的能下载到的sdk最高版本只有3.2.5.6。

因此,需要我们手动下载系统源码,自己完成sdk的编译才行,我这里是基于3.2 beta4的系统源码自行编译出来的full-sdk。

启用相机打开预览画面核心流程与代码实现

(1)动态权限申请

需要获取ohos.permission.CAMERA权限

(2)相机相关API操作流程

上面是相机完整功能使用的时序图,这里我们先只按照时序图中的流程只实现预览部分。

(3)配合XComponent组件完成相机预览流的输出

XComponent组件中通过XComponentController的getXComponentSurfaceId方法可以获取到sufaceId,然后通过相机管理对象cameraManager.createPreviewOutput这个关键方法可以绑定该surface,从而实现预览画面的输出。

启用相机打开预览画面代码实现

import camera from '@ohos.multimedia.camera'

const PERMISSIONS: Array<string> = [
  'ohos.permission.CAMERA']
let previewWidth;
let previewHeight;
@Entry
@Component
struct Index {
  private mXComponentController: XComponentController = new XComponentController()
  private surfaceId: string = '-1'

  async initCamera(surfaceId: string){
    //动态获取隐私权限
    let context = getContext(this) as any
    await context.requestPermissionsFromUser(PERMISSIONS)
    console.log('grantPermission,requestPermissionsFromUser');
    // 创建CameraManager对象
    let cameraManager = await camera.getCameraManager(context)
    if (!cameraManager) {
      console.error('Failed to get the CameraManager instance');
    }
    // 获取相机列表
    let cameraArray = await cameraManager.getSupportedCameras()
    if (!cameraArray) {
      console.error('Failed to get the cameras');
    }
    for (let index = 0; index < cameraArray.length; index++) {
      console.log('cameraId : ' + cameraArray[index].cameraId)                          // 获取相机ID
      console.log('cameraPosition : ' + cameraArray[index].cameraPosition)              // 获取相机位置
      console.log('cameraType : ' + cameraArray[index].cameraType)                      // 获取相机类型
      console.log('connectionType : ' + cameraArray[index].connectionType)              // 获取相机连接类型
    }

    // 创建相机输入流
    let cameraInput = await cameraManager.createCameraInput(cameraArray[0])

    //  打开相机
    await cameraInput.open().then(() => {
      console.log('opencamera succ.');
    }).catch(function(err){
      console.log("opencamera failed with error:"+ err);
    });

    // 获取相机设备支持的输出流能力
    let cameraOutputCap = await cameraManager.getSupportedOutputCapability(cameraArray[0]);
    if (!cameraOutputCap) {
      console.error("outputCapability outputCapability == null || undefined")
    } else {
      console.log("outputCapability: " + JSON.stringify(cameraOutputCap));
    }

    //获取相机支持的输出能力--支持的预览配置信息
    let previewProfilesArray = cameraOutputCap.previewProfiles;
    if (!previewProfilesArray) {
      console.error("createOutput previewProfilesArray == null || undefined")
    }else{
      console.log("previewProfiles:"+JSON.stringify(previewProfilesArray[0]))
      previewWidth = previewProfilesArray[0].size.width;
      previewHeight = previewProfilesArray[0].size.height;
    }

    // 创建预览输出流,其中参数 surfaceId 参考下面 XComponent 组件,预览流为XComponent组件提供的surface
    let previewOutput = await cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId)
    if (!previewOutput) {
      console.error("Failed to create the PreviewOutput instance.")
    }else{
      console.log("create the PreviewOutput instance succ.")
    }

    //创建会话
    let captureSession = await cameraManager.createCaptureSession()
    if (!captureSession) {
      console.error('Failed to create the CaptureSession instance.');
      return;
    }
    console.log('Callback returned with the CaptureSession instance.' + captureSession);

    // 开始配置会话
    await captureSession.beginConfig().then(()=>{
      console.log('captureSession beginConfig succ');
    }).catch(function(err){
      console.log("captureSession beginConfig failed with error:"+ err);
    });
 
    // 向会话中添加相机输入流
    await captureSession.addInput(cameraInput).then(() => {
      console.log('captureSession addInput instance is added.');
    }).catch(function(err){
      console.log("captureSession addInput failed with error:"+ err);
    });

    // 向会话中添加预览输入流
    await captureSession.addOutput(previewOutput).then(() => {
      console.log('captureSession addOutput previewOutput instance is added.');
    }).catch(function(err){
      console.log("captureSession addOutput previewOutput failed with error:"+ err);
    });

    // 提交会话配置
    await captureSession.commitConfig().then(() => {
      console.log('captureSession commitConfig success.');
    }).catch(function(err){
      console.log("captureSession commitConfig failed with error:"+ err);
    });
    // 启动会话
    await captureSession.start().then(() => {
      console.log('captureSession start success.');
    }).catch(function(err){
      console.log("captureSession start failed with error:"+ err);
    });
  }

  build() {
    Flex() {
      XComponent({                                                                     // 创建XComponent
        id: '',
        type: 'surface',
        libraryname: '',
        controller: this.mXComponentController
      })
        .onLoad(() => {                                                                  // 设置onload回调
          // 设置Surface宽高(1920*1080),预览尺寸设置参考前面 previewProfilesArray 获取的当前设备所支持的预览分辨率大小去设置
          this.mXComponentController.setXComponentSurfaceSize({surfaceWidth:previewWidth,surfaceHeight:previewHeight})
          // 获取Surface ID
          this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
          this.initCamera(this.surfaceId)
        })
        .width('100%')                                                                 // 设置XComponent宽度
        .height('100%')                                                                // 设置XComponent高度
    }
  }

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenHarmony3.2 beta4上照相机的使用之1--开启照相机预览画面 的相关文章

  • Python requests下载超大文件/批量下载文件

    一 下载超大文件 使用 python 下载超大文件 直接全部下载 文件过大 可能会造成内存不足 这时候要使用 requests 的 stream 模式 主要代码如下 iter content 一块一块的遍历要下载的内容 iter lines
  • 11年做安卓开发至今,我失业了,我跟CSDN的缘分

    今天来写篇自己的文章 自己工作的文章 11年毕业到现在 我彻底失业了 是真的失业了 不过失业我觉得没什么可怕 至少干了这些年 也攒下了一些生活费 至少饿不死就行了 我失业也是因为自己有业 并不害怕 从11年做开发 那个时候就边做开发 边思考
  • 解决ubuntu远程ssh连接不了问题

    安装openssh server sudo apt get install openssh server 在 etc ssh目录下 vim sshd config 发现该文件只可读 在终端输入命令 sudo passwd 然后输入当前用户的
  • 【MySQL】表的基本操作

    1 数据类型 1 1 数值类型 数据类型 大小 说明 bit M M指定位数 默认为1 二进制 M范围从1到64 存储数值范围从0到2 M 1 tinyint 1字节 smallint 2字节 int 4字节 bigint 8字节 floa
  • 使用python对银行信息管理系统的简单实现

    一 首先是用户属性的类 class account object 储存用户信息的类 def init self id1 name tel money self id id1 账户 self name name 姓名 self tel tel
  • C语言实现推箱子小游戏

    一 设计目的 用简单的C语言知识制作的推箱子游戏 通过上下左右键将所有箱子移动到目标位置 2 让我们更好地了解和巩固C语言知识 并实际运用 同时运用一些不太常见的知识点 二 功能描述 1 模块功能 本程序可分为初始界面 进行游戏 判定通关三
  • 业务流程图怎么画?3步+8张案例,5分钟教你快速上手!

    业务流程图能很好地帮助我们梳理业务 高效表达需求 尤其是产品经理在梳理业务时 经常会用到业务流程图 业务流程图会在产品经理画原型图前 帮助梳理产品业务流程 避免做无用功 今天从业务历程图的基本介绍 常用场景和绘制方法三方面介绍 让大家对业务
  • 什么是Java?

    刚开始学习Java时 对于老师讲述的Java的发展历程毫无兴趣 觉得只要会用就行了 直到有一天我的朋友突然问我 你们学的Java是什么呀 面对他突如其来的问题 我一下有点不知所措 刚想开口却又不知道说些什么 只能慢慢的吐出那几个字 一门编程
  • Anaconda + jupyter notebook + jupyter lab环境配置

    1 更换源 1 1 pip源 pip config set global index url https pypi tuna tsinghua edu cn simple pip config set install trusted hos
  • MySQL备份与恢复

    2 3 1备份MySQL数据库 在MySQL的bin目录下 有一个名为mysqldump的可执行文件 将该bin目录添加到环境变量中 可以利用它在 命令提示符 环境下来备份数据库 语法格式如下 mysqldump opt 要备份的数据库名
  • java动态加载jar包,并运行其中的类和方法

    flink 相关 https www toutiao com article 6883793897495986691 动态加载jar包 在实际开发中经常会需要用到 尤其涉及平台和业务的关系的时候 业务逻辑部分可以独立出去交给业务方管理 业务
  • 数据类型分类

    分为四种类型
  • 【NLP】第 6 章 :微调预训练模型

    到目前为止 我们已经了解了如何使用包含预训练模型的huggingface API 来创建简单的应用程序 如果您可以从头开始并仅使用您自己的数据来训练您自己的模型 那不是很棒吗 如果您没有大量空闲时间或计算资源可供使用 那么使用迁移学习 是最
  • Pipenv:作为 Python 开发人员为什么应该使用它

    Pipenv 是一个旨在将所有打包世界中最好的东西带到 Python 世界的工具 它将 Pipfile pip 和 virtualenv 整合到一个命令中 它会自动为您的项目创建和管理虚拟环境 并在您安装 卸载包时从您的 Pipfile 添
  • 通过微信小程序实现登录功能

    后端服务器可以在CSDN上开通 价格优惠 CSDN开发云 https img home csdnimg cn images 20220518054835 png https dev csdn net activity utm source
  • Unity3D小程序部署与开发

    Unity3D目前已经支持微信小程序开发 目前正处于公测阶段 可以参考文档 这样我们只需要在unity本地开发完 一键导出微信小程序工程发布即可 0 下载小程序开发工具与Unity 微信小程序插件 小程序开发工具 wechat devtoo
  • // SPDX-License-Identifier: MIT

    上述声明是指明你写的智能合约采用什么样的对外开放标准 该标准规定了别人是否拥有各种使用权利 其中 MIT 标准说明其他人可以随便用该源码 但出问题不负责
  • 单个IMU实现精确的轨迹重构

    惯性传感器 IMU 被广泛用于导航 运动状态研究 人体运动和步态分析等领域 然而 由于IMU的固有误差和测量误差 尤其是漂移误差 很少有人尝试基于IMU实现精确的轨迹重建 尤其是使用单个IMU 尽管如此 与视觉 红外线和超声波定位技术相比
  • Coco-LIC:紧耦合激光雷达-惯性相机里程计SOTA方案

    点击下方 卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 gt gt 点击进入 自动驾驶之心 SLAM 技术交流群 论文作者 Xiaolei Lang 编辑 自动驾驶之心 笔者个人理解 机器人在弱结构化 弱纹理环境中的状态估计
  • 眼神矫正AI一键修改你的眼睛眼球,直视相机!

    1 系统要求 软件运行支持32位 64位window 10 11系统 硬性要求 英伟达 RTX20系列或者更高级别 其他要求无 2 下载安装 链接 百度网盘 请输入提取码 提取码 1234 复制这段内容后打开百度网盘手机App 操作更方便哦

随机推荐

  • MySQL数据库基础学习Day1:创建库与表(数据库操作、表操作、数据操作:增删改查)

    目录 一 字段类型 二 约束 三 使用命令连接 1 打开终端cmd 运行命令 2 登录成功后 输入如下命令查看效果 3 退出登录 四 数据库操作 1 显示所有数据库 2 创建数据库 3 查询当前使用的数据库 4 切换数据库 5 删除数据库
  • 获取memcache缓存下所有的键值对信息

    缓存是可以在很大程度上提高网站的响应速度和整体性能的工具 但是如果贸然直接修改数据库的数据但是没有更新缓存就很容易使得前端页面上仍然加载脏数据的 因此 对于一个WEB站点来说 缓存内容的管理显得尤为重要 笔者最近做的小项目中用到了memca
  • 讲一点点自动驾驶技术(2)自动驾驶定位系统 part 1 GNSS和激光雷达部分

    最近又有点时间了 来唠一唠自动驾驶技术的第一个部分 定位系统吧 对于一辆自动驾驶的车辆来说 定位技术是关键技术之一 在这一篇小Q来说一说不同的定位技术 这里面包括GNSS全球导航卫星系统 激光雷达 LiDAR 高精度地图 视觉里程计和其他的
  • 开机自动启动_Mac如何彻底关掉开机自动开启的应用程序

    使用Mac的小伙伴有没有这样的烦恼 电脑一开机 一堆烦人的软件就自动开启了 让人很懊恼 如何才能彻底关掉开机自动开启的应用程序 mac开机启动项怎么设置 开机启动项要怎么禁止 今天macdown小编就带大家解决这个懊恼的问题 感兴趣的朋友就
  • 最优服务次序问题-贪心算法

    1 最优服务次序问题 1 问题描述 设有n 个顾客同时等待一项服务 顾客i需要的服务时间为ti 1 lt i lt n 应如何安排n个顾客的服务次序才能使平均等待时间达到最小 平均等待时间是n 个顾客等待服务时间的总和除以n 2 编程任务
  • Better-Scroll可滚动区域问题

    解决Better Scroll可滚动区域的问题 Better Scroll在决定有多少区域可以滚动时 是根据scrollerHeight属性决定 scrollerHeight属性石根据放Better Scroll的content中的子组件的
  • c语言中常见的几种排序方式详解补充优化及总结

    在学习过程中我们常常会遇到各种排序的问题 给定一个数组 从大到小排序或者从小到大排序等等 我们通常有思路去解决这个问题 但是在敲代码的过程中可能会出现各种问题 我们接下来详细介绍三种常用且好理解的方法 扩展我们的思路 冒泡排序 假如给我们一
  • 计算机组成原理3--<存储体系>

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 存储器的分类 二 存储器的层次结构 1 主存储器 总结 一 存储器的分类 按存储介质分类 半导体存储器 磁存储器 纸带存储器 光存储器等 按照存取方式分类 随机
  • ajax和getjson区别,jQuery中$ .getJSON()和$ .ajax()之间的区别

    内容型强 gt 您无需在调用MVC控制器操作时指定内容类型 只有在调用ASP NET AJAX ScriptServices 和页面方法时才需要特殊的 application json charset utf 8 内容类型 jQuery的默
  • c语言简单介绍&编译过程

    标题 为什么要写 include 编译过程 编译 链接 为什么是 lt gt 中写的是stdio h 函数 Java中称为方法 C语言是大部分人接触的第一门计算机语言 虽然很多学校将C作为一门初始语言 但是其难度还是有的 计算机只具有一维思
  • OLED滚动显示

    少年 一 滚动显示介绍 1 1 具体介绍 1 2 水平滚动命令 1 3 垂直滚动命令 二 代码模块 三 显示效果 四 总结 五 参考资料 一 滚动显示介绍 1 1 具体介绍 SSD1306 OLED驱动芯片 指令详解 1 2 水平滚动命令
  • 普通二本,去过阿里外包,到现在年薪40W+的高级测试工程师,我的两年转行经历...

    我是一个普通二本大学机械专业毕业 14年毕业 16年转行 目前做IT行业的软件测试已经有3年多 职位是高级软件测试工程师 坐标上海 我想现在我也有一点资格谈论关于转行这个话题 希望你在决定转行之前 首先搞清楚转行是你内心热爱还是一时冲动 如
  • 解决pycharm连接mysql报错(DB Navigator-Connection error)

    在上一篇连接操作里 可能不是每个电脑都能一次成功 https blog csdn net forever up422 article details 122631096 spm 1001 2014 3001 5502 如果在最后测试一步出现
  • 【云原生之Docker实战】使用Docker部署BookStack文档管理系统

    云原生之Docker实战 使用Docker部署BookStack文档管理系统 一 BookStack介绍 1 BookStack简介 2 BookStack功能 二 检查本地docker环境 1 检查docker服务状态 2 检查docke
  • Java学习路线(超详细)

    目录 前言 1 学习Java基础知识 2 掌握面向对象编程 OOP 概念 3 熟悉Java集合框架 4 学习Java异常处理 5 学习Java IO 6 掌握Java多线程编程 7 学习Java网络编程 8 学习Java数据库编程 9 学习
  • Android 设置屏幕自动关闭时间

    Android 设置屏幕自动关闭时间 在Android设备上 屏幕的自动关闭时间是指手机在没有操作的情况下 屏幕自动关闭的时间间隔 默认情况下 Android设备的屏幕自动关闭时间为几分钟 但用户可以根据自己的需求进行修改 本文将介绍如何通
  • Linux·字符设备再分析

    Linux系统将设备分成字符设备 块设备 网络设备三类 用户程序调用硬件的过程如下 一 用户级 内核级和系统调用 Linux Unix系统下的进程运行分为用户态和进程态两种状态 我们的应用程序通常仅在用户态下运行 出于保护内核资源的需要 用
  • 安装cargo-generate各种坑【mac + wasm + rust 环境搭建】

    cargo install cargo generate 如果报openssl错误千万别再去装了 各种坑 这个cargo generate可以手动下载安装的 先贴上我的报错信息 run pkg config fail pkg config
  • Python队列Queue详解,超详细

    Queue queue模块简介 queue Queue maxsize 0 queue LifoQueue maxsize 0 queue PriorityQueue maxsize 0 queue SimpleQueue 3 7 新版功能
  • OpenHarmony3.2 beta4上照相机的使用之1--开启照相机预览画面

    随着OpenHarmony的版本更新 在3 2上已经提供了非常丰富的API来调用照相机 此处讲解的是原生的使用相机的流程 并发像Android普通应用开发一样通过一个intent直接调用系统相机应用进行拍照 根据原生的调用相机的API可以让