鸿蒙应用开发之媒体(相机)

一、概述

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

1、基本概念

  • 相机静态能力

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

  • 物理相机

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

  • 逻辑相机

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

  • 帧捕获

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

  • 单帧捕获

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

  • 多帧捕获

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

  • 循环帧捕获

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

2、约束与限制

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

3、开发流程

img

二、开发前的一些说明及必要步骤

1、三个重要接口

包名 功能
ohos.media.camera.CameraKit 相机功能入口类。获取当前支持的相机列表及其静态能力信息,创建相机对象。
ohos.media.camera.device 相机设备操作类。提供相机能力查询、相机配置、相机帧捕获、相机状态回调等功能。
ohos.media.camera.params 相机参数类。提供相机属性、参数和操作结果的定义。

2、权限申请

相机涉及到的权限有如下四个

权限名称 权限属性值 是否必选
相机权限 ohos.permission.CAMERA 必选
录音权限 ohos.permission.MICROPHONE 可选(需要录像时申请)
存储权限 ohos.permission.WRITE_USER_STORAGE 可选(需要保存图像及视频到设备的外部存储时申请)
位置权限 ohos.permission.LOCATION 可选(需要保存图像及视频位置信息时申请)

在配置文件中声明权限,这里图方便,我把以上四个权限都请求了,做Demo的时候就不用一个一个加了

"reqPermissions": [
  {
    
    
    "name": "ohos.permission.CAMERA",
    "name": "ohos.permission.MICROPHONE",
    "name": "ohos.permission.LOCATION",
    "name": "ohos.permission.WRITE_USER_STORAGE"
  }

image-20210120141535344

MainAbilityOnStart方法中对权限进行请求

public class MainAbility extends Ability {
    
    
    @Override
    public void onStart(Intent intent) {
    
    
        super.onStart(intent);
        super.setMainRoute(MainAbilitySlice.class.getName());
        String[] permissions = {
    
    "ohos.permission.CAMERA"
                , "ohos.permission.MICROPHONE"
                , "ohos.permission.LOCATION"
                , "ohos.permission.WRITE_USER_STORAGE"};
        requestPermissionsFromUser(permissions, 0);
    }
}

image-20210120142147059

三、相机设备的创建

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) 注销相机使用状态回调。

基于HarmonyOS实现一个相机应用,无论将来想应用到哪个或者哪些设备上,都必须先创建一个独立的相机设备,然后才能继续相机的其他操作。

流程

public class MainAbilitySlice extends AbilitySlice {
    
    
    private static HiLogLabel hiLogLabel = new HiLogLabel(3, 1, "MainAbility");
    private EventHandler eventHandler = new EventHandler(EventRunner.create("CameraCb"));
    private CameraStateCallback cameraStateCallback = new CameraStateCallback() {
    
    
        @Override
        public void onCreated(Camera camera) {
    
    
            super.onCreated(camera);
            HiLog.info(hiLogLabel, "创建相机设备");
        }

        @Override
        public void onCreateFailed(String cameraId, int errorCode) {
    
    
            super.onCreateFailed(cameraId, errorCode);
            HiLog.info(hiLogLabel, "创建相机设备失败,cameraId = " + cameraId + ",errorCode = " + errorCode);
        }

        @Override
        public void onConfigured(Camera camera) {
    
    
            super.onConfigured(camera);
            HiLog.info(hiLogLabel, "配置相机设备");
        }

        @Override
        public void onPartialConfigured(Camera camera) {
    
    
            super.onPartialConfigured(camera);
            HiLog.info(hiLogLabel, "使用了addDeferredSurfaceSize配置了相机");

        }

        @Override
        public void onConfigureFailed(Camera camera, int errorCode) {
    
    
            super.onConfigureFailed(camera, errorCode);
            HiLog.info(hiLogLabel, "配置相机设备失败");

        }

        @Override
        public void onReleased(Camera camera) {
    
    
            super.onReleased(camera);
            HiLog.info(hiLogLabel, "释放相机设备");

        }

        @Override
        public void onFatalError(Camera camera, int errorCode) {
    
    
            super.onFatalError(camera, errorCode);
            HiLog.info(hiLogLabel, "onFatalError错误");
        }

        @Override
        public void onCaptureRun(Camera camera) {
    
    
            super.onCaptureRun(camera);
            HiLog.info(hiLogLabel, "onCaptureRun错误");
        }

        @Override
        public void onCaptureIdle(Camera camera) {
    
    
            super.onCaptureIdle(camera);
            HiLog.info(hiLogLabel, "onCaptureIdle错误");
        }
    };
    private Button mBtn1;

    @Override
    public void onStart(Intent intent) {
    
    
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        String[] permissions = {
    
    "ohos.permission.CAMERA"
                , "ohos.permission.MICROPHONE"
                , "ohos.permission.LOCATION"
                , "ohos.permission.WRITE_USER_STORAGE"};
        requestPermissionsFromUser(permissions, 0);
        mBtn1 = (Button) findComponentById(ResourceTable.Id_btn1);
        mBtn1.setClickedListener(component -> {
    
    
            createCamera();
        });
    }

    /**
     * @description 测试创建相机设备
     * @author PengHuAnZhi
     * @date 2021/1/20 14:28
     */
    private void createCamera() {
    
    
        /*获取唯一的CameraKit对象是创建新的相机应用的第一步操作*/
        CameraKit cameraKit = CameraKit.getInstance(this.getContext());
        /*如果此步骤操作失败,相机可能被占用或无法使用。如果被占用,必须等到相机释放后才能重新获取CameraKit对象*/
        if (cameraKit != null) {
    
    
            try {
    
    
                String[] cameraIds = cameraKit.getCameraIds();
                if (cameraIds.length <= 0) {
    
    
                    HiLog.info(hiLogLabel, "设备无可用相机设备!");
                } else {
    
    
                    //遍历设备有可以用的相机设备
                    for (String id : cameraIds) {
    
    
                        //相机硬件信息
                        CameraInfo cameraInfo = cameraKit.getCameraInfo(id);
                        //获取相机朝向信息
                        int facingType = cameraInfo.getFacingType();
                        //获取逻辑相机ID。
                        String logicalId = cameraInfo.getLogicalId();
                        List<String> physicalIdList = cameraInfo.getPhysicalIdList();
                        HiLog.info(hiLogLabel, "id = " + id + ",朝向信息为" + facingType + ",逻辑相机id = " + logicalId);
                        HiLog.info(hiLogLabel, "对应的物理相机id列表如下");
                        for (String str : physicalIdList) {
    
    
                            //获取物理相机连接方式
                            int deviceLinkType = cameraInfo.getDeviceLinkType(str);
                            HiLog.info(hiLogLabel, "物理相机id = " + str + ",连接方式 = " + deviceLinkType);
                        }
                        //相机能力信息(比如支持的分辨率列表等)。
                        CameraAbility cameraAbility = cameraKit.getCameraAbility(id);
                        /*CameraAbility类下的API更多,需要就上官方文档查吧,这里只示范一个*/
                        //获取当前相机支持的闪光灯取值范围
                        int[] supportedFlashMode = cameraAbility.getSupportedFlashMode();
                        HiLog.info(hiLogLabel, "闪光灯取值范围为 = " + Arrays.toString(supportedFlashMode));
                        HiLog.info(hiLogLabel, "---------------------------------");
                    }
                    if (cameraStateCallback == null) {
    
    
                        HiLog.info(hiLogLabel, "cameraStateCallback为Null!");
                    }
                    if (eventHandler == null) {
    
    
                        HiLog.info(hiLogLabel, "eventHandler为Null!");
                    }
                    /*第一个参数cameraId可以是上一步获取的逻辑相机列表中的任何一个相机ID。第二和第三个参数负责相机创建和相机运行时的数据和状态检测,务必保证在整个相机运行周期内有效。*/
                    cameraKit.createCamera(cameraIds[0], cameraStateCallback, eventHandler);
                }
            } catch (Exception e) {
    
    
                HiLog.info(hiLogLabel, "获取设备支持的逻辑相机列表错误");
            }
        } else {
    
    
            HiLog.info(hiLogLabel, "获取CameraKit失败了");
        }
    }

    @Override
    public void onActive() {
    
    
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
    
    
        super.onForeground(intent);
    }
}

测试结果

image-20210120160516119

失败??

调了一个多小时,还是不行,一点参考资料也没有,鸿蒙要怎么学???????

待更,不学了。

猜你喜欢

转载自blog.csdn.net/qq_43509535/article/details/112887256
今日推荐