Android Camera的使用 (一)

本文详细介绍如何使用 Android 的 Camera 类进行拍照和录像。包括权限配置、Camera 对象的创建与使用、预览显示设置、方向调整等关键步骤。此外,还提供了完整的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言
在android 5.0 之后 官方已经不推荐Camear这个类了,而是推荐 android.hardware.camera2 包下的api.但我们还是有必要学习一下。

Camera这个类可以被用来照相、start/top相机预览、将图像帧编码成video。它对于相机服务相当于一个客户端,它管理者真正的硬件Camera。

要访问硬件Camera我们必须在AndroidManifest.xml中声明相机权限。还必须确保AndroidManifest.xml 包含相机功能的声明( < uses- feature >)。比如如果想使用相机的 auto-focus,就必须在AndroidManifest.xml中声明:

<uses-permission android:name="android.permission.CAMERA" />
 <uses-feature android:name="android.hardware.camera" />
 <uses-feature android:name="android.hardware.camera.autofocus" />

使用这个类照相可以分为以下几步:
1、使用 Camera的 opent(int).创建一个实例
2、通过getParameters(). 获得默认的参数
3、如果必要的话,通过setParameters(Camera.Parameters). 修改参数
4、使用 setDisplayOrientation(int)改正当前预览的方向
5、初始化一个SurfaceHolder,并通过 setPreviewDisplay(SurfaceHolder). 设置,如果没有设置将不能开始预览
6、 调用startPreview()开始预览,拍照前必须开始预览
7、调用 takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback) 等待image 数据
8、拍完照之后,如果还想继续拍照重新调用 startPreview()
9、调用 stopPreview()停止预览
10、调用 release() 释放。应用程序应该在 onPause()时立即调用该方法,在onResume重新打开。

使用这个类录像分为以下几步:
1、和上文描述的一样 创建一个实例,之后开启预览
2、调用unlock() 去允许media process 访问camera
3、通过MediaRecord的 setCamera(Camear camera)
4、当结束录制之后,调用reconnect() 去请求,并re-lock Camera
5、如果希望继续拍照或者录像,重新调用 startPreviews()
6、调用stopPreview() 和 release()结束

下面是一个简单的拍照示例:

public class CameraActivity extends BaseActivity {

    private static final String TAG = "CameraActivity";

    @BindView(R.id.btn_take_picture)
    Button btnTakePicture;
    @BindView(R.id.btn_start_record)
    Button btnStartRecord;
    @BindView(R.id.surfaceView)
    SurfaceView surfaceView;

    private SurfaceHolder holder;
    private Camera mCamera;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_camera);
        ButterKnife.bind(this);
        initView();
    }

    private void initCamera() {
        /**
         * Step 1.
         * 获得一个Camera实例,(默认获得为后置摄像头)
         */
        if(mCamera==null){
            mCamera = Camera.open();
        }

        /**
         * Step 2.
         * 获得默认的参数
         */
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureFormat(ImageFormat.JPEG);

        /**
         * Stop 3.
         * 设置参数
         */
        mCamera.setParameters(parameters);

        /**
         * Step 4.
         * 修正当前的方向
         */
        setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);

        /**
         * Step 5.
         * 设置 SurfaceHolder
         */
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /**
         * Step 6.
         * 开始预览
         */
        mCamera.startPreview();
    }

    public static void setCameraDisplayOrientation(Activity activity,
                                                   int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

    private void initView() {
        holder = surfaceView.getHolder();
        holder.addCallback(callback);
        holder.setKeepScreenOn(true);
    }


    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
        initCamera();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
        /**
         * Step 9. 停止预览
         */
        mCamera.stopPreview();
        /**
         * Step 10. 释放
         */
        mCamera.release();
        mCamera = null;
    }

    @OnClick({R.id.btn_take_picture, R.id.btn_start_record})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_take_picture:
                /**
                 * Step 7.
                 * 拍照
                 */
                mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        if (data != null) {

                            /**
                             * Step 8. 重新开始预览
                             */
                            mCamera.startPreview();
                            writeImage2Sdcard(data);
                        }
                    }
                });
                break;
            case R.id.btn_start_record:
                break;
        }
    }

    private void writeImage2Sdcard(final byte[] data) {
        new Thread() {
            @Override
            public void run() {
                FileOutputStream out = null;
                try {
                    out = new FileOutputStream(new File("sdcard/test",
                            System.currentTimeMillis() + ".jpg"));
                    out.write(data);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (out != null) try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            initCamera();
            Log.i(TAG, "surfaceCreated: ");
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Log.i(TAG, "surfaceChanged: ");
            setCameraDisplayOrientation(CameraActivity.this,
                    Camera.CameraInfo.CAMERA_FACING_BACK,mCamera);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.i(TAG, "surfaceDestroyed: ");
        }
    };

如果需要录制视频的话加入以下代码:

 if (!started) {
                    started = true;
                    btnStartRecord.setText("结束录像");
                    mediaRecorder = new MediaRecorder();
                    /**
                     * 录像 Step A.
                     */
                    mCamera.unlock();
                    /**
                     * 录像 Step B.
                     */
                    mediaRecorder.setCamera(mCamera);
                    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
                    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//                    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
                    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
                    mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+
                            File.separator+System.currentTimeMillis()+".3gp");
                    try {
                        mediaRecorder.prepare();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mediaRecorder.start();
//
                } else {
                    started = false;
                    btnStartRecord.setText("开始录像");
                    mediaRecorder.stop();
                    mediaRecorder.reset();
                    mediaRecorder.release();
                    /**
                     * 录像 Step C.
                     */
                    try {
                        mCamera.reconnect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    mCamera.lock();

                    /**
                     * 录像 Step D.
                     */
                    mCamera.startPreview();
                }

最后完整代码如下:

public class CameraActivity extends BaseActivity {

    private static final String TAG = "CameraActivity";

    @BindView(R.id.btn_take_picture)
    Button btnTakePicture;
    @BindView(R.id.btn_start_record)
    Button btnStartRecord;
    @BindView(R.id.surfaceView)
    SurfaceView surfaceView;

    private SurfaceHolder holder;
    private Camera mCamera;

    private MediaRecorder mediaRecorder;
    private boolean started;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_camera);
        ButterKnife.bind(this);
        initView();
    }

    private void initCamera() {
        /**
         * Step 1.
         * 获得一个Camera实例,(默认获得为后置摄像头)
         */
        if (mCamera == null) {
            mCamera = Camera.open();
        }

        /**
         * Step 2.
         * 获得默认的参数
         */
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureFormat(ImageFormat.JPEG);

        /**
         * Stop 3.
         * 设置参数
         */
        mCamera.setParameters(parameters);

        /**
         * Step 4.
         * 修正当前的方向
         */
        setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);

        /**
         * Step 5.
         * 设置 SurfaceHolder
         */
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /**
         * Step 6.
         * 开始预览
         */
        mCamera.startPreview();
    }

    public static void setCameraDisplayOrientation(Activity activity,
                                                   int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

    private void initView() {
        holder = surfaceView.getHolder();
        holder.addCallback(callback);
        holder.setKeepScreenOn(true);
    }


    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
        initCamera();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
        /**
         * Step 9. 停止预览
         */
        mCamera.stopPreview();
        /**
         * Step 10. 释放
         */
        mCamera.release();
        mCamera = null;
    }

    @OnClick({R.id.btn_take_picture, R.id.btn_start_record})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_take_picture:
                /**
                 * Step 7.
                 * 拍照
                 */
                mCamera.takePicture(null, null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        if (data != null) {

                            /**
                             * Step 8. 重新开始预览
                             */
                            mCamera.startPreview();
                            writeImage2Sdcard(data);
                        }
                    }
                });
                break;
            case R.id.btn_start_record:
                if (!started) {
                    started = true;
                    btnStartRecord.setText("结束录像");
                    mediaRecorder = new MediaRecorder();
                    /**
                     * 录像 Step A.
                     */
                    mCamera.unlock();
                    /**
                     * 录像 Step B.
                     */
                    mediaRecorder.setCamera(mCamera);
                    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
                    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//                    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
                    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
                    mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+
                            File.separator+System.currentTimeMillis()+".3gp");
                    try {
                        mediaRecorder.prepare();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mediaRecorder.start();
//
                } else {
                    started = false;
                    btnStartRecord.setText("开始录像");
                    mediaRecorder.stop();
                    mediaRecorder.reset();
                    mediaRecorder.release();
                    /**
                     * 录像 Step C.
                     */
                    try {
                        mCamera.reconnect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    mCamera.lock();

                    /**
                     * 录像 Step D.
                     */
                    mCamera.startPreview();
                }


                break;
        }
    }


    private void writeImage2Sdcard(final byte[] data) {
        new Thread() {
            @Override
            public void run() {
                FileOutputStream out = null;
                try {
                    out = new FileOutputStream(new File("sdcard/test",
                            System.currentTimeMillis() + ".jpg"));
                    out.write(data);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (out != null) try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            initCamera();
            Log.i(TAG, "surfaceCreated: ");
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Log.i(TAG, "surfaceChanged: ");
            setCameraDisplayOrientation(CameraActivity.this,
                    Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.i(TAG, "surfaceDestroyed: ");
        }
    };

}

权限:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <uses-permission android:name="android.permission.CAMERA"></uses-permission>
    <uses-feature android:name="android.hardware.camera"></uses-feature>
    <uses-feature android:name="android.hardware.camera.autofocus"></uses-feature>

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值