Android调用摄像头实现

1. 流程概述

在本文中,我们将学习如何在Android应用程序中调用摄像头。以下是整个过程的流程图:

stateDiagram
    [*] --> 检测摄像头权限
    检测摄像头权限 --> 初始化摄像头
    初始化摄像头 --> 配置摄像头
    配置摄像头 --> 开启预览
    开启预览 --> 拍照
    拍照 --> 停止预览

2. 实现步骤

2.1 检测摄像头权限

在AndroidManifest.xml文件中添加相机权限:

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

2.2 初始化摄像头

在Activity或Fragment的代码中,首先需要获取摄像头服务:

private Camera mCamera;
...
void initCamera() {
    mCamera = Camera.open();
}

2.3 配置摄像头

在初始化摄像头之后,我们需要配置摄像头的参数,比如预览尺寸、图片格式等。以下是一个示例:

void configureCamera() {
    Camera.Parameters params = mCamera.getParameters();
    params.setPreviewSize(width, height);
    params.setPictureFormat(ImageFormat.JPEG);
    mCamera.setParameters(params);
}

2.4 开启预览

在配置摄像头之后,我们可以通过SurfaceView来显示摄像头预览:

void startPreview(SurfaceHolder holder) {
    mCamera.setPreviewDisplay(holder);
    mCamera.startPreview();
}

2.5 拍照

拍照是调用摄像头的核心功能。在拍照之前,需要先对相机进行一些设置,然后调用takePicture()方法:

void takePhoto() {
    mCamera.autoFocus(new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            if (success) {
                mCamera.takePicture(null, null, mPictureCallback);
            }
        }
    });
}

2.6 停止预览

拍照完成后,我们可以停止预览并释放摄像头资源:

void stopPreview() {
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
}

3. 代码示例

下面是一个完整的示例代码,展示了如何实现Android调用摄像头的过程:

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private Camera mCamera;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSurfaceView = findViewById(R.id.surfaceView);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        initCamera();
        configureCamera();
        startPreview(holder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // 需要处理surface改变的情况
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        stopPreview();
    }

    void initCamera() {
        mCamera = Camera.open();
    }

    void configureCamera() {
        Camera.Parameters params = mCamera.getParameters();
        params.setPreviewSize(width, height);
        params.setPictureFormat(ImageFormat.JPEG);
        mCamera.setParameters(params);
    }

    void startPreview(SurfaceHolder holder) {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    }

    void takePhoto() {
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    mCamera.takePicture(null, null, mPictureCallback);
                }
            }
        });
    }

    void stopPreview() {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // 处理拍摄的照片
        }
    };
}

4. 状态图

以下是摄像头调用过程的状态图:

stateDiagram
    [*] --> 检测