Android相机开发

作者: Thor_果冻 | 来源:发表于2019-03-06 19:10 被阅读125次

    Android相机开发

    申请权限

    <uses-permission android:name="android.permission.CAMERA" />
    <!--可以防止APP被安装到没有相机的Android设备上(目前仅Google Play支持)-->
    <uses-feature android:name="android.hardware.camera" />
    

    动态权限不要忘了

    创建一个可以预览的界面

    1.创建一个新工程

    2.在新创建的工程中activity中布局文件

    <FrameLayout
        android:id="@+id/preview_f"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    

    3.创建一个相机预览的view 继承SurfaceView

    最新都开始用TextureView,关于SurfaceView/TextureView

    • SurfaceView是一个有自己Surface的View。界面渲染可以放在单独线程而不是主线程中。它更像是一个Window,自身不能做变形和动画。
    • TextureView同样也有自己的Surface。但是它只能在拥有硬件加速层层的Window中绘制,它更像是一个普通View,可以做变形和动画。

    更多关于SurfaceView与TextureView区别的内容可以参考这篇文章Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView.

    官方给出的方案,图片来自于Android平台Camera开发实践指南:

    官方给出的方案
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    
        private final SurfaceHolder mHolder;
        private Camera mCamera;
    
        public CameraPreview(Context context) {
            super(context);
            mHolder = getHolder();
            mHolder.addCallback(this);
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            //surface第一次创建时回调
            //打开相机
            mCamera = Camera.open();
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            //surface变化的时候回调(格式/大小)
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            //surface销毁的时候回调
            mHolder.removeCallback(this);
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }
    

    4.在activity中添加

    public class MainActivity extends AppCompatActivity {
    
        private FrameLayout mFrameLayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initCamera();
        }
    
        private void initCamera() {
            CameraPreview preview = new CameraPreview(this);
            mFrameLayout.addView(preview);
        }
    
        private void initView() {
            mFrameLayout = (FrameLayout) findViewById(R.id.preview_f);
        }
    }
    

    至此可以显示一个相机界面,并有图像显示。

    添加偏好设置

    如分辨率、闪光灯、对焦等。

    通过当前界面的相机camera对象获取起设置的参数getParameters()

    预览分辨率

    • parameters.getSupportedPreviewSizes()获取相机支持的所有预览分辨率

    预览格式

    具体参照ImageFormat或者自己Google

    • parameters.getSupportedPreviewFormats()获取相机支持的所有预览格式

    照片分辨率

    • parameters.getSupportedPictureSizes()获取相机支持的所有图片分辨率

    图片格式

    具体参照ImageFormat或者自己Google

    • parameters.getSupportedPictureFormats()获取相机支持的所有图片格式

    视频分辨率

    parameters.getSupportedVideoSizes()获取相机支持的所有视频分辨率

    对焦模式

    • parameters.getSupportedFocusModes()获取相机支持的所有对焦模式

    曝光补偿

    • parameters.getMinExposureCompensation()获取相机支持的最低曝光补偿
    • parameters.getMaxExposureCompensation()获取相机支持的最高曝光补偿

    闪光灯模式

    • parameters.getSupportedFlashModes()获取相机支持的闪光灯模式

    白平衡

    • parameters.getSupportedWhiteBalance()获取相机支持的白平衡

    场景

    parameters.getSupportedSceneModes()获取相机支持的场景

    声明GPS权限

    想要拍到的照片中包含GPS信息

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    

    代码如下

    int numberOfCameras = Camera.getNumberOfCameras();
    Log.d("123===", "相机个数===" + numberOfCameras);
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    for (int i = 0; i < numberOfCameras; i++) {
        Camera.getCameraInfo(i, cameraInfo);
        //后置:0 CAMERA_FACING_BACK; 前置:1 CAMERA_FACING_FRONT
        Log.d("123===", "当前相机信息=" + cameraInfo.facing);
    }
    
    
    Camera camera = mPreview.getCamera();
    Camera.Parameters parameters = camera.getParameters();
    
    Log.d("123===", "预览分辨率-----------");
    List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
    for (Camera.Size previewSize : supportedPreviewSizes) {
        Log.d("123===", previewSize.width + "---" + previewSize.height);
    }
    Log.d("123===", "预览分辨率-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "获得相机支持的图片预览格式-----------ImageFormat");
    List<Integer> supportedPreviewFormats = parameters.getSupportedPreviewFormats();
    for (Integer supportedPreviewFormat : supportedPreviewFormats) {
        Log.d("123===", supportedPreviewFormat + "");
    }
    Log.d("123===", "获得相机支持的图片预览格式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "照片分辨率-----------");
    List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
    for (Camera.Size pictureSize : supportedPictureSizes) {
        Log.d("123===", pictureSize.width + "---" + pictureSize.height);
    }
    Log.d("123===", "照片分辨率-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "获得相机支持的图片格式-----------ImageFormat");
    List<Integer> supportedPictureFormats = parameters.getSupportedPictureFormats();
    for (Integer supportedPreviewFormat : supportedPictureFormats) {
        Log.d("123===", supportedPreviewFormat + "");
    }
    Log.d("123===", "获得相机支持的图片格式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "视频分辨率-----------");
    List<Camera.Size> supportedVideoSizes = parameters.getSupportedVideoSizes();
    for (Camera.Size supportedVideoSize : supportedVideoSizes) {
        Log.d("123===", supportedVideoSize.width + "---" + supportedVideoSize.height);
    
    }
    Log.d("123===", "视频分辨率-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    Log.d("123===", "对焦模式-----------ImageFormat");
    List<String> supportedFocusModes = parameters.getSupportedFocusModes();
    for (String supportedFocusMode : supportedFocusModes) {
        Log.d("123===", supportedFocusMode + "");
    }
    Log.d("123===", "对焦模式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    Log.d("123===", "曝光补偿-----------");
    int minExposureCompensation = parameters.getMinExposureCompensation();
    int maxExposureCompensation = parameters.getMaxExposureCompensation();
    Log.d("123===", "最高=" + maxExposureCompensation);
    Log.d("123===", "最低=" + minExposureCompensation);
    Log.d("123===", "曝光补偿-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "支持闪光灯模式-----------");
    List<String> supportedFlashModes = parameters.getSupportedFlashModes();
    for (String supportedFlashMode : supportedFlashModes) {
        Log.d("123===", "闪光模式--->" + supportedFlashMode);
    }
    Log.d("123===", "支持闪光灯模式-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    
    Log.d("123===", "支持白平衡-----------");
    List<String> supportedWhiteBalance = parameters.getSupportedWhiteBalance();
    for (String s : supportedWhiteBalance) {
        Log.d("123===", "--->" + s);
    }
    Log.d("123===", "支持白平衡-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    
    Log.d("123===", "场景-----------");
    List<String> supportedSceneModes = parameters.getSupportedSceneModes();
    for (String s : supportedSceneModes) {
        Log.d("123===", "--->" + s);
    }
    Log.d("123===", "场景-----------");
    Log.d("123===", "");
    Log.d("123===", "");
    

    拍照,视频,对焦

    假如需要使用原生拍照功能的话,Camera#takePicture()

    拍照和视频都是网上那一套流程,具体的因为时间原因暂时先这样了。

    相机预览和保存注意事项

    下面三张图片引用自:Android: Camera相机开发详解(中) ——实现预览、拍照、保存照片等功能

    • 相机预览方向
    相机预览方向
    • 采集的图像方向
    采集的图像方向
    • 前置摄像头预览与保存一致
    前置摄像头预览与保存一致

    参考

    相关文章

      网友评论

        本文标题:Android相机开发

        本文链接:https://www.haomeiwen.com/subject/zowxpqtx.html