HarmonyOS学习路之开发篇—多媒体开发(相机开发 一)

这篇具有很好参考价值的文章主要介绍了HarmonyOS学习路之开发篇—多媒体开发(相机开发 一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

HarmonyOS相机模块支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照、连拍和录像等。

基本概念

  • 相机静态能力

    用于描述相机的固有能力的一系列参数,比如朝向、支持的分辨率等信息。

  • 物理相机

    物理相机就是独立的实体摄像头设备。物理相机ID是用于标志每个物理摄像头的唯一字串。

  • 逻辑相机

    逻辑相机是多个物理相机组合出来的抽象设备,逻辑相机通过同时控制多个物理相机设备来完成相机某些功能,如大光圈、变焦等功能。逻辑摄像机ID是一个唯一的字符串,标识多个物理摄像机的抽象能力。

  • 帧捕获

    相机启动后对帧的捕获动作统称为帧捕获。主要包含单帧捕获、多帧捕获、循环帧捕获。

  • 单帧捕获

    指的是相机启动后,在帧数据流中捕获一帧数据,常用于普通拍照。

  • 多帧捕获

    指的是相机启动后,在帧数据流中连续捕获多帧数据,常用于连拍。

  • 循环帧捕获

    指的是相机启动后,在帧数据流中一直捕获帧数据,常用于预览和录像。

约束与限制

  • 在同一时刻只能有一个相机应用在运行中。
  • 相机模块内部有状态控制,开发者必须按照指导文档中的流程进行接口的顺序调用,否则可能会出现调用失败等问题。
  • 为了开发的相机应用拥有更好的兼容性,在创建相机对象或者参数相关设置前请务必进行能力查询。

相机开发流程

相机模块主要工作是给相机应用开发者提供基本的相机API接口,用于使用相机系统的功能,进行相机硬件的访问、操作和新功能开发。相机的开发流程如图所示:

HarmonyOS学习路之开发篇—多媒体开发(相机开发 一)

接口说明

相机模块为相机应用开发者提供了3个包的内容,包括方法、枚举、以及常量/变量,方便开发者更容易地实现相机功能。详情请查阅对应开发场景。

包名

功能

ohos.media.camera.CameraKit

相机功能入口类。获取当前支持的相机列表及其静态能力信息,创建相机对象。

ohos.media.camera.device

相机设备操作类。提供相机能力查询、相机配置、相机帧捕获、相机状态回调等功能。

ohos.media.camera.params

相机参数类。提供相机属性、参数和操作结果的定义。

相机权限申请

在使用相机之前,需要申请相机的相关权限,保证应用拥有相机硬件及其他功能权限,相机涉及权限如下表。

权限名称

权限属性值

是否必选

相机权限

ohos.permission.CAMERA

必选

录音权限

ohos.permission.MICROPHONE

可选(需要录像时申请)

存储权限

ohos.permission.WRITE_MEDIA

可选(需要保存图像及视频到设备的外部存储时申请)

位置权限

ohos.permission.MEDIA_LOCATION

可选(需要保存图像及视频位置信息时申请)

相机设备创建

CameraKit类是相机的入口API类,用于获取相机设备特性、打开相机,其接口如下表。

接口名

描述

createCamera​(String cameraId, CameraStateCallback callback, EventHandler handler)

创建相机对象。

getCameraAbility​(String cameraId)

获取指定逻辑相机或物理相机的静态能力。

getCameraIds​()

获取当前逻辑相机列表。

getCameraInfo​(String cameraId)

获取指定逻辑相机的信息。

getInstance​(Context context)

获取CameraKit实例。

registerCameraDeviceCallback​(CameraDeviceCallback callback, EventHandler handler)

注册相机使用状态回调。

unregisterCameraDeviceCallback​(CameraDeviceCallback callback)

注销相机使用状态回调。

在实现一个相机应用之前必须先创建一个独立的相机设备,然后才能继续相机的其他操作。相机设备创建的建议步骤如下:

1. 通过CameraKit.getInstance(Context context)方法获取唯一的CameraKit对象

private void openCamera(){
    // 获取CameraKit对象
    CameraKit cameraKit = CameraKit.getInstance(getApplicationContext());
    if (cameraKit == null) {
        // 处理cameraKit获取失败的情况 
    }
}

如果此步骤操作失败,相机可能被占用或无法使用。如果被占用,必须等到相机释放后才能重新获取CameraKit对象。

2. 通过getCameraIds()方法,获取当前使用的设备支持的逻辑相机列表。逻辑相机列表中存储了当前设备拥有的所有逻辑相机ID,如果列表不为空,则列表中的每个ID都支持独立创建相机对象;否则,说明正在使用的设备无可用的相机,不能继续后续的操作。

try {
    // 获取当前设备的逻辑相机列表
    String[] cameraIds = cameraKit.getCameraIds();
    if (cameraIds.length <= 0) {
        HiLog.error(LABEL, "cameraIds size is 0");
    }
} catch (IllegalStateException e) {
    // 处理异常
}

还可以继续查询指定相机ID的静态信息:

调用getDeviceLinkType​(String physicalId)方法获取物理相机连接方式;

调用getCameraInfo(String cameraId)方法查询相机硬件朝向等信息;

调用getCameraAbility(String cameraId)方法查询相机能力信息(比如支持的分辨率列表等)。

CameraInfo的主要接口

接口名

描述

getDeviceLinkType​(String physicalId)

获取物理相机连接方式。

getFacingType​()

获取相机朝向信息。

getLogicalId​()

获取逻辑相机ID。

getPhysicalIdList​()

获取对应的物理相机ID列表。

CameraAbility的主要接口

接口名

描述

getSupportedSizes​(int format)

根据格式查询输出图像的分辨率列表。

getSupportedSizes​(Class<T> clazz)

根据Class类型查询分辨率列表。

getParameterRange​(ParameterKey.Key<T> parameter)

获取指定参数能够设置的值范围。

getPropertyValue​(PropertyKey.Key<T> property)

获取指定属性对应的值。

getSupportedAeMode​()

获取当前相机支持的自动曝光模式。

getSupportedAfMode​()

获取当前相机支持的自动对焦模式。

getSupportedFaceDetection​()

获取相机支持的人脸检测类型范围。

getSupportedFlashMode​()

当前相机支持的闪光灯取值范围。

getSupportedParameters​()

当前相机支持的参数设置。

getSupportedProperties​()

获取当前相机的属性列表。

getSupportedResults​()

获取当前相机支持的参数设置可返回的结果列表。

getSupportedZoom​()

获取相机支持的变焦范围。

3. 通过createCamera(String cameraId, CameraStateCallback callback, EventHandler handler)方法,创建相机对象,此步骤执行成功意味着相机系统的硬件已经完成了上电。

// 前置相机类型
int frontCamera = CameraInfo.FacingType.CAMERA_FACING_FRONT;
// 后置相机类型
int backCamera = CameraInfo.FacingType.CAMERA_FACING_BACK;
// 其他相机类型
int otherCamera = CameraInfo.FacingType.CAMERA_FACING_OTHERS;

// 选择想要创建的相机类型,如果不存在该类型相机,则返回false
boolean isCameraCreated = openCameraByFacingType(frontCamera);
// 根据类型创建相机的方法
private boolean openCameraByFacingType(int facingType) {
    CameraKit cameraKit = CameraKit.getInstance(getApplicationContext());
    for(String cameraId : cameraKit.getCameraIds()) {
        CameraInfo cameraInfo = cameraKit.getCameraInfo(cameraId);
        if(facingType == cameraInfo.getFacingType()) {
            cameraKit.createCamera(cameraId, cameraStateCallback, eventHandler);
            return true;
        }
    }
    return false;
}

参数cameraId可以是上一步获取的逻辑相机列表中的任何一个相机ID。

第二和第三个参数负责相机创建和相机运行时的数据和状态检测,请务必保证在整个相机运行周期内有效。

private final class CameraStateCallbackImpl extends CameraStateCallback {
    @Override
    public void onCreated(Camera camera) {
         // 创建相机设备
    }
 
    @Override
    public void onConfigured(Camera camera) {
        // 配置相机设备
    }

    @Override
    public void onPartialConfigured(Camera camera) {
        // 当使用了addDeferredSurfaceSize配置了相机,会接到此回调
    }

    @Override
    public void onReleased(Camera camera) { 
       // 释放相机设备
    }
}
 
// 相机创建和相机运行时的回调
CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl();
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
 
// 执行回调的EventHandler
EventHandler eventHandler = new EventHandler(EventRunner.create("CameraCb"));

至此,相机设备的创建已经完成。相机设备创建成功会在CameraStateCallback中触发onCreated(Camera camera)回调。在进入相机设备配置前,请确保相机设备已经创建成功。否则会触发相机设备创建失败的回调,并返回错误码,需要进行错误处理后,重新执行相机设备的创建。

相机设备配置

创建相机设备成功后,在CameraStateCallback中会触发onCreated(Camera camera)回调,并且带回Camera对象,用于执行相机设备的操作。

当一个新的相机设备成功创建后,首先需要对相机进行配置,调用configure(CameraConfig)方法实现配置。相机配置主要是设置预览、拍照、录像用到的Surface(详见ohos.agp.graphics.Surface),没有配置过Surface,相应的功能不能使用。

为了进行相机帧捕获结果的数据和状态检测,还需要在相机配置时调用setFrameStateCallback(FrameStateCallback, EventHandler)方法设置帧回调。

// Surface提供对象
private SurfaceProvider surfaceProvider;

private void initSurface() {
    surfaceProvider = new SurfaceProvider(this);
    DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig(     
        ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
    surfaceProvider.setLayoutConfig(params);    
    surfaceProvider.pinToZTop(false);
    surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack());
    ((ComponentContainer) 
        findComponentById(ResourceTable.Id_surface_container)).addComponent(surfaceProvider);
}

private FrameStateCallback frameStateCallbackImpl = new FrameStateCallback(){
    @Override    
    public void onFrameStarted(Camera camera, FrameConfig frameConfig, long frameNumber, long timestamp) {
        ...    
    }
    @Override
    public void onFrameProgressed(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
        ...
    }
    @Override
    public void onFrameFinished(Camera camera, FrameConfig frameConfig, FrameResult frameResult) {
        ...
    }
    @Override
    public void onFrameError(Camera camera, FrameConfig frameConfig, int errorCode, FrameResult frameResult) {
        ...
    }
    @Override
    public void onCaptureTriggerStarted(Camera camera, int captureTriggerId, long firstFrameNumber) {
        ...
    }
    @Override
    public void onCaptureTriggerFinished(Camera camera, int captureTriggerId, long lastFrameNumber) {
        ...
    }
    @Override
    public void onCaptureTriggerInterrupted(Camera camera, int captureTriggerId) {
        ...
    }
};

// 相机设备
private Camera cameraDevice;
// 相机预览模板
private Surface previewSurface;
// 相机配置模板
private CameraConfig.Builder cameraConfigBuilder;
// 图像帧数据接收处理对象
private ImageReceiver imageReceiver;

private final class CameraStateCallbackImpl extends CameraStateCallback {
    @Override
    public void onCreated(Camera camera) {
        cameraDevice = camera;
        previewSurface = surfaceProvider.getSurfaceOps().get().getSurface();
        cameraConfigBuilder = camera.getCameraConfigBuilder();
        if (cameraConfigBuilder == null) {
            HiLog.error(LABEL, "onCreated cameraConfigBuilder is null");
            return;
        }
        // 配置预览的Surface
        cameraConfigBuilder.addSurface(previewSurface);
        // 配置拍照的Surface
        cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
        // 配置帧结果的回调
        cameraConfigBuilder.setFrameStateCallback(frameStateCallbackImpl, eventHandler);
        try {
            // 相机设备配置
            camera.configure(cameraConfigBuilder.build());
        } catch (IllegalArgumentException e) {
            HiLog.error(LABEL, "Argument Exception");
        } catch (IllegalStateException e) {
            HiLog.error(LABEL, "State Exception");
        }
    }
}

相机配置成功后,在CameraStateCallback中会触发onConfigured(Camera camera)回调,然后才可以执行相机帧捕获相关的操作。

 CameraConfig.Builder的主要接口

接口名

描述

addSurface​(Surface surface)

相机配置中增加Surface。

build​()

相机配置的构建类。

removeSurface​(Surface surface)

移除先前添加的Surface。

setFrameStateCallback​(FrameStateCallback callback, EventHandler handler)

设置用于相机帧结果返回的FrameStateCallback和Handler。

addDeferredSurfaceSize(Size surfaceSize, Class<T> clazz)

添加延迟Surface的尺寸、类型。

addDeferredSurface(Surface surface)

设置延迟的Surface,此Surface的尺寸和类型必须和使用addDeferredSurfaceSize配置的一致。文章来源地址https://www.toymoban.com/news/detail-498304.html

到了这里,关于HarmonyOS学习路之开发篇—多媒体开发(相机开发 一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 鸿蒙HarmonyOS开发实战—多媒体开发(音频开发 一)

    HarmonyOS音频模块支持音频业务的开发,提供音频相关的功能,主要包括音频播放、音频采集、音量管理和短音播放等。 基本概念 采样 采样是指将连续时域上的模拟信号按照一定的时间间隔采样,获取到离散时域上离散信号的过程。 采样率 采样率为每秒从连续信号中提取并

    2024年01月24日
    浏览(51)
  • 多媒体开发之cgo

         go语言作为近十年来优秀的现代开发语言的代表,由于继承了c语言的简洁和很多现代语言的表达方式,在广泛的应用场景中得到众多爱好者的喜爱,如何将go和c、c++进行联合开发,拓展整个开发生态,不用重复造轮子,掌握cgo可以让你得心应手的在c和go之间传递信息,

    2024年02月16日
    浏览(49)
  • Android多媒体功能开发(2)——FileProvider

    使用系统多媒体界面需要在我们的应用和其他应用之间通过Intent传递音频、图片、视频文件的信息。随着Android版本的升级,对应用数据安全性方面的限制越来越多。 Android 6以后不允许应用在外部存储随便创建目录,只能在Android规定的应用自己的文件目录下创建目录,该目录

    2024年02月14日
    浏览(48)
  • qt6 多媒体开发代码分析(二、录音)

    常见的音频编码格式包括MP3、AAC、OGG、WMA、FLAC等,它们之间具有以下区别: 编码方式不同:这些编码格式采用的编码算法不同,例如MP3和AAC使用有损压缩算法,而FLAC使用无损压缩算法。 压缩率和文件大小不同:由于采用的编码算法不同,不同格式的音频文件压缩率和文件大

    2024年02月07日
    浏览(39)
  • HTML-多媒体嵌入-MDN文档学习笔记

    查看更多学习笔记:GitHub:LoveEmiliaForever MDN中文官网 将图片放入网页 可以使用 img/ 来将图片嵌入网页,它是一个空元素,最少只需 src 属性即可工作 src 指向图片资源的地址,是 img/ 正常工作必不可少的属性 ❗️除非有必要,否则 永远不要 把 src 指向其它网站上的图片,这

    2024年02月20日
    浏览(52)
  • Android多媒体功能开发(12)——使用Camera类拍照

    Android上用摄像头拍照、录视频有两套API可用,Android5.0(API21)之前使用android.hardware.Camera类,之后推荐使用android.hardware.camera2包。目前这两套API都可以使用,Camera类用起来比较简单易懂,但功能少灵活性差,所以现在降级使用;Camera2框架功能强大,对摄像头的控制灵活,但由于

    2023年04月13日
    浏览(43)
  • Android多媒体功能开发(11)——使用AudioRecord类录制音频

    AudioRecord类优点是能录制到缓冲区,能够实现边录边播(AudioRecord + AudioTrack)以及对音频的实时处理(如QQ电话)。缺点是输出是PCM格式的原始采集数据,如果直接保存成音频文件,不能够被播放器播放,所以必须用代码实现数据编码以及压缩。 使用AudioRecord录音的基本步骤是

    2023年04月09日
    浏览(45)
  • 【软考程序员学习笔记】——多媒体基础知识

    目录 🍊 一、多媒体的概念及分类 多媒体的分类 🍊二、声音信号的数字化过程 采样 量化 编码 🍊三、常见音频文件格式 🍊四、图形/图像区别  图形 图像 🍊五、常见图像文件格式 🍊六、常见视频文件格式 🍊七、显示器的基本参数 传播信息的载体,如语言、文字、图

    2024年02月09日
    浏览(49)
  • SDL库入门:掌握跨平台游戏开发和多媒体编程

    SDL (Simple DirectMedia Layer) 是一个跨平台的开源多媒体库,它提供了访问音频、键盘、鼠标、操纵杆以及图形硬件的底层接口。SDL 可用于开发游戏、仿真器、媒体播放器等多种类型的应用程序。 1.1 SDL 的背景与应用领域 SDL 由 Sam Lantinga 开发,最早发布于 1998 年。SDL 的设计目标是

    2024年02月02日
    浏览(46)
  • 15-1_Qt 5.9 C++开发指南_Qt多媒体模块概述

    多媒体功能指的主要是计算机的音频和视频的输入、输出、显示和播放等功能,Qt 的多媒体模块为音频和视频播放、录音、摄像头拍照和录像等提供支持,甚至还提供数字收音机的支持。本章将介绍 Qt 多媒体模块的功能和使用。 Qt 多媒体模块提供了很多类,可以实现如下的

    2024年02月13日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包