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

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

 相机帧捕获

Camera操作类,包括相机预览、录像、拍照等功能接口。

接口名

描述

triggerSingleCapture​(FrameConfig frameConfig)

启动相机帧的单帧捕获。

triggerMultiCapture​(List<FrameConfig> frameConfigs)

启动相机帧的多帧捕获。

configure​(CameraConfig config)

配置相机。

flushCaptures​()

停止并清除相机帧的捕获,包括循环帧/单帧/多帧捕获。

getCameraConfigBuilder​()

获取相机配置构造器对象。

getCameraId​()

获取当前相机的ID。

getFrameConfigBuilder​(int type)

获取指定类型的相机帧配置构造器对象。

release​()

释放相机对象及资源。

triggerLoopingCapture​(FrameConfig frameConfig)

启动或者更新相机帧的循环捕获。

stopLoopingCapture​()

停止当前相机帧的循环捕获。

启动预览(循环帧捕获)

用户一般都是先看见预览画面才执行拍照或者其他功能,所以对于一个普通的相机应用,预览是必不可少的。启动预览的建议步骤如下:

1. 通过getFrameConfigBuilder(FRAME_CONFIG_PREVIEW)方法获取预览配置模板,常用帧配置项见下表,更多的帧配置项以及详细使用方法请参考API接口说明的FrameConfig.Builder部分。

接口名

描述

是否必选

addSurface(Surface surface)

配置预览surface和帧的绑定。

setAfMode(int afMode, Rect rect)

配置对焦模式。

setAeMode(int aeMode, Rect rect)

配置曝光模式。

setZoom(float value)

配置变焦值。

setFlashMode(int flashMode)

配置闪光灯模式。

setFaceDetection(int type, boolean isEnable)

配置人脸检测或者笑脸检测。

setParameter(Key<T> key, T value)

配置其他属性(如自拍镜像等)。

setMark(Object mark)

配置一个标签,后续可以从FrameConfig中通过Object getMark()拿到标签,判断两个是否相等,相等就说明是同一个配置。

setCoordinateSurface(Surface surface)

配置坐标系基准Surface,后续计算Ae/Af等区域都会基于此Surface为基本的中心坐标系,不设置默认使用添加的第一个Surface。

2. 通过triggerLoopingCapture(FrameConfig)方法实现循环帧捕获(如预览/录像)。

private final class CameraStateCallbackImpl extends CameraStateCallback {
    @Override
    public void onConfigured(Camera camera) {
        // 获取预览配置模板
        frameConfigBuilder = camera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW);
        // 配置预览Surface
        frameConfigBuilder.addSurface(previewSurface);
        previewFrameConfig = frameConfigBuilder.build();
        try {
            // 启动循环帧捕获
            int triggerId = camera.triggerLoopingCapture(previewFrameConfig);
        } catch (IllegalArgumentException e) {
            HiLog.error(LABEL, "Argument Exception");
        } catch (IllegalStateException e) {
            HiLog.error(LABEL, "State Exception");
         }
    }
}

经过以上的操作,相机应用已经可以正常进行实时预览了。在预览状态下,开发者还可以执行其他操作,比如:

当预览帧配置更改时,可以通过triggerLoopingCapture(FrameConfig)方法实现预览帧配置的更新;

// 预览帧变焦值变更
frameConfigBuilder.setZoom(1.2f);
// 调用triggerLoopingCapture方法实现预览帧配置更新
triggerLoopingCapture(frameConfigBuilder.build());

通过stopLoopingCapture()方法停止循环帧捕获(停止预览)。

// 停止预览帧捕获
camera.stopLoopingCapture()

实现拍照(单帧捕获)

拍照功能属于相机应用的最重要功能之一,而且照片质量对用户至关重要。相机模块基于相机复杂的逻辑,从应用接口层到器件驱动层都已经默认的做好了最适合用户的配置,这些默认配置尽可能地保证用户拍出的每张照片的质量。发起拍照的建议步骤如下:

1. 通过getFrameConfigBuilder(FRAME_CONFIG_PICTURE)方法获取拍照配置模板,并且设置拍照帧配置,如下表

接口名

描述

是否必选

FrameConfig.Builder addSurface(Surface)

实现拍照Surface和帧的绑定。

必选

FrameConfig.Builder setImageRotation(int)

设置图片旋转角度。

可选

FrameConfig.Builder setLocation(Location)

设置图片地理位置信息。

可选

FrameConfig.Builder setParameter(Key<T>, T)

配置其他属性(如自拍镜像等)。

可选

2. 拍照前准备图像帧数据的接收实现

// 图像帧数据接收处理对象       
private ImageReceiver imageReceiver;
// 执行回调的EventHandler
private EventHandler eventHandler = new EventHandler(EventRunner.create("CameraCb"));
// 拍照支持分辨率
private Size pictureSize;

// 单帧捕获生成图像回调Listener
private final ImageReceiver.IImageArrivalListener imageArrivalListener = new ImageReceiver.IImageArrivalListener() {
    @Override
    public void onImageArrival(ImageReceiver imageReceiver) {
        StringBuffer fileName = new StringBuffer("picture_"); 
        fileName.append(UUID.randomUUID()).append(".jpg"); // 定义生成图片文件名
        File myFile = new File(dirFile, fileName.toString()); // 创建图片文件
        imageSaver = new ImageSaver(imageReceiver.readNextImage(), myFile); // 创建一个读写线程任务用于保存图片
        eventHandler.postTask(imageSaver); // 执行读写线程任务生成图片
    }
};

// 保存图片, 图片数据读写,及图像生成见run方法
class ImageSaver implements Runnable {
    private final Image myImage;
    private final File myFile;

    ImageSaver(Image image, File file) {
        myImage = image;
        myFile = file;
    }

    @Override
    public void run() {
        Image.Component component = myImage.getComponent(ImageFormat.ComponentType.JPEG);
        byte[] bytes = new byte[component.remaining()];
        component.read(bytes);
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(myFile);
            output.write(bytes); // 写图像数据
        } catch (IOException e) {
            HiLog.error(LABEL, "save picture occur exception!");
        } finally {
            if (output != null) {
                try {
                    output.close(); // 关闭流
                } catch (IOException e) {
                    HiLog.error(LABEL, "image release occur exception!");
                }
            }
            myImage.release();
        }
    }
}
private void takePictureInit() {
    List<Size> pictureSizes = cameraAbility.getSupportedSizes(ImageFormat.JPEG); // 获取拍照支持分辨率列表
    pictureSize = getPictureSize(pictureSizes) // 根据拍照要求选择合适的分辨率
    imageReceiver = ImageReceiver.create(Math.max(pictureSize.width, pictureSize.height),
        Math.min(pictureSize.width, pictureSize.height), ImageFormat.JPEG, 5); // 创建ImageReceiver对象,注意create函数中宽度要大于高度;5为最大支持的图像数,请根据实际设置。
    imageReceiver.setImageArrivalListener(imageArrivalListener);
}

3. 通过triggerSingleCapture(FrameConfig)方法实现单帧捕获(如拍照)。

private void capture() {
    // 获取拍照配置模板
    framePictureConfigBuilder = cameraDevice.getFrameConfigBuilder(FRAME_CONFIG_PICTURE);
    // 配置拍照Surface
    framePictureConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
    // 配置拍照其他参数
    framePictureConfigBuilder.setImageRotation(90);
    try {
        // 启动单帧捕获(拍照)
        cameraDevice.triggerSingleCapture(framePictureConfigBuilder.build());
    } catch (IllegalArgumentException e) {
        HiLog.error(LABEL, "Argument Exception");
    } catch (IllegalStateException e) {
        HiLog.error(LABEL, "State Exception");
    }
}

为了捕获到质量更高和效果更好的图片,还可以在帧结果中实时监测自动对焦和自动曝光的状态,一般而言,在自动对焦完成,自动曝光收敛后的瞬间是发起单帧捕获的最佳时机。

实现连拍(多帧捕获)

连拍功能方便用户一次拍照获取多张照片,用于捕捉精彩瞬间。同普通拍照的实现流程一致,但连拍需要使用triggerMultiCapture(List<FrameConfig> frameConfigs)方法。

启动录像(循环帧捕获)

启动录像和启动预览类似,但需要另外配置录像Surface才能使用。

1. 录像前需要进行音视频模块的配置。

private Source source; // 音视频源
private AudioProperty.Builder audioPropertyBuilder; // 音频属性构造器
private VideoProperty.Builder videoPropertyBuilder; // 视频属性构造器
private StorageProperty.Builder storagePropertyBuilder; // 音视频存储属性构造器
private Recorder mediaRecorder; // 录像操作对象
private String recordName; // 音视频文件名
private Size mRecordSize; // 录像分辨率

private void initMediaRecorder() {
    videoPropertyBuilder.setRecorderBitRate(10000000); // 设置录制比特率
    int rotation = DisplayManager.getInstance().getDefaultDisplay(this).get().getRotation();
    videoPropertyBuilder.setRecorderDegrees(getOrientation(rotation)); // 设置录像方向
    videoPropertyBuilder.setRecorderFps(30); // 设置录制采样率
    videoPropertyBuilder.setRecorderHeight(Math.min(recordSize.height, recordSize.width)); // 设置录像支持的分辨率,需保证width > height
    videoPropertyBuilder.setRecorderWidth(Math.max(recordSize.height, recordSize.width));
    videoPropertyBuilder.setRecorderVideoEncoder(Recorder.VideoEncoder.H264); // 设置视频编码方式
    videoPropertyBuilder.setRecorderRate(30); // 设置录制帧率
    source.setRecorderAudioSource(Recorder.AudioSource.MIC); // 设置录制音频源
    source.setRecorderVideoSource(Recorder.VideoSource.SURFACE); // 设置视频窗口
    mediaRecorder.setSource(source); // 设置音视频源
    mediaRecorder.setOutputFormat(Recorder.OutputFormat.MPEG_4); // 设置音视频输出格式
    StringBuffer fileName = new StringBuffer("record_"); // 生成随机文件名
    fileName.append(UUID.randomUUID()).append(".mp4");
    recordName = fileName.toString();
    File file = new File(dirFile, recordName); // 创建录像文件对象
    storagePropertyBuilder.setRecorderFile(file); // 设置存储音视频文件名
    mediaRecorder.setStorageProperty(storagePropertyBuilder.build());
    audioPropertyBuilder.setRecorderAudioEncoder(Recorder.AudioEncoder.AAC); // 设置音频编码格式
    mediaRecorder.setAudioProperty(audioPropertyBuilder.build()); // 设置音频属性
    mediaRecorder.setVideoProperty(videoPropertyBuilder.build()); // 设置视频属性
    mediaRecorder.prepare(); // 准备录制
    HiLog.info(LABEL, "initMediaRecorder end");
}

2. 配置录像帧,启动录像

private final class CameraStateCallbackImpl extends CameraStateCallback {
    @Override
    public void onConfigured(Camera camera) {
        // 获取录像配置模板
        frameConfigBuilder = camera.getFrameConfigBuilder(FRAME_CONFIG_RECORD);
        // 配置预览Surface
        frameConfigBuilder.addSurface(previewSurface);
        // 配置录像的Surface
        mRecorderSurface = mediaRecorder.getVideoSurface();
        frameConfigBuilder.addSurface(mRecorderSurface);
        previewFrameConfig = frameConfigBuilder.build();
        try {
            // 启动循环帧捕获
            int triggerId = camera.triggerLoopingCapture(previewFrameConfig);
        } catch (IllegalArgumentException e) {
            HiLog.error(LABEL, "Argument Exception");
        } catch (IllegalStateException e) {
            HiLog.error(LABEL, "State Exception");
        }
    }
}

相机设备释放

使用完相机后,必须通过release()来关闭相机和释放资源,否则可能导致其他相机应用无法启动。一旦相机被释放,它所提供的操作就不能再被调用,否则会导致不可预期的结果,或是会引发状态异常。

相机设备释放的示例代码如下:文章来源地址https://www.toymoban.com/news/detail-506909.html

private void releaseCamera() {
    if (camera != null) {
        // 关闭相机和释放资源
        camera.release();
        camera = null;
    }
    // 拍照配置模板置空
    framePictureConfigBuilder = null;
    // 预览配置模板置空
    previewFrameConfig = null;
}

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

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

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

相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    2024年02月13日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包