优秀案例

Android自定义Camera

2020-06-20  本文已影响0人  ZhijunHong

Android自定义Camera相机

转载请表明出处https://www.jianshu.com/p/e7f4973fbe76,谢谢~

写在前面

Android Framework层为各种不同的Camera和Camera的特色功能提供了支持,使得你可以很方便的在应用使用拍照和录像功能。如果希望快速实现拍照与录制视频的方法是使用Intent方式调用系统提供的相机功能;当然,如果系统提供的方式不足以满足项目的需求,你就需要自定义Camera相机。本篇博客会通过Intent方式和自定义Camera两部分介绍如何使用相机功能。

传送门:https://github.com/zhijunhong/custom_view/tree/master/camera

Intent实现方式

  1. 权限申请

  1. 代码实现

    • 申请Camera和存储权限
        private void openCapturePicOrVideo() {
            PermissionX.init(this)
                    .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .request(new RequestCallback() {
                        @Override
                        public void onResult(boolean allGranted, List<String> grantedList, List<String> deniedList) {
                            if (allGranted) {
                              Toast.makeText(SystemCameraActivity.this, "All permissions are granted", Toast.LENGTH_LONG).show();
    
                                //拍照
                                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);     // create a file to save the image
                                intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
                                startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    
                                //拍摄视频
    //                            Intent intent1 = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    //                            fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);       // create a file to save the video
    //                            intent1.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);      // set the image file name
    //                            intent1.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);     // set the video image quality to high
    //                            // start the Video Capture Intent
    //                            startActivityForResult(intent1, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
    
                            } else {
                                Toast.makeText(SystemCameraActivity.this, "These permissions are denied: $deniedList", Toast.LENGTH_LONG).show();
                            }
                        }
                    });
        }
    

    Android6.0以后的系统,需要在代码中申请敏感权限。这里为了方便起见,直接使用郭神的开源框架PermissionX申请Camera和存储权限

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                String tip;
                if (data != null) {
                    tip = "Image saved to:" + data.getParcelableExtra("data");               //系统目录
                } else {
                    tip = "Image saved to:" + fileUri;                                       //指定目录
                }
                Toast.makeText(this, tip, Toast.LENGTH_LONG).show();
            } else if (resultCode == RESULT_CANCELED) {
            } else {
            }
        }

//        if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
//            if (resultCode == RESULT_OK) {
//                Toast.makeText(this, "Video saved to:\n" +
//                        data.getData(), Toast.LENGTH_LONG).show();
//            } else if (resultCode == RESULT_CANCELED) {
//            } else {
//            }
//        }
    }

Notice:这里重点说明一下MediaStore.EXTRA_OUTPUT这个参数,定义了一个Uri对象来指定存放图片的路径与文件名。这个设置信息是可选的,但是强烈建议添加。如果你不指定这个值,相机程序会使用默认的文件名保存图片到默认的位置,这个值可以从Intent.getData()的字段中获取到。

自定义Camera方式

以下内容,重点分析一下如何通过系统提供的Camera底层API,诸如Camera的打开或者称之为获取、Camera预览和Camera停止预览等,来定制相机功能,实现我们项目中特定的需求

  1. 权限申请

参考Intent方式中的权限申请部分,不再赘述。

  1. 代码实现

//点击拍照按钮
mBtnCapture.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // get an image from the camera
        mCamera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                FileUtils.saveTakePicture(data);
                //关闭界面
                finish();
            }
        });
    }
});

相机硬件是一个共享资源,它必须被小心谨慎的管理使用,因此你的程序不应该和其他可能使用相机硬件的程序有冲突。

当你的程序执行完任务后,需要使用camers.realease()方法来释放相机对象。如果你的相机没有合理的释放相机,后续包括你自己的应用在内的所有的相机应用,都将无法正常打开相机并且可能导致程序崩溃。

@Override
protected void onPause() {
    super.onPause();
    CameraManger.getInstance().releaseCamera(mCamera);
}
/**
 * 释放相机资源
 */
public void releaseCamera(Camera camera) {
    if (camera != null) {
        camera.release();      //release the camera for other applications
        camera = null;
    }
}

此致,希望可以对正在研究如何自定义Camera的小伙伴提供一些思路和帮助!

最后,别忘了start哟~

上一篇 下一篇

猜你喜欢

热点阅读