Android原生相机:排横版照片

概述

在以往的手机摄影中,垂直拍摄照片是主流。然而,随着智能手机屏幕越来越大,用户越来越倾向于横向拍摄,以适应更广阔的视野。本文将介绍如何使用Android原生相机应用开发,实现排横版照片的功能。

准备工作

在编写代码之前,我们需要进行一些准备工作:

1. 环境设置

确保你的开发环境已经正确设置并且安装了Android Studio。如果你还没有安装,请根据官方文档中的说明进行安装。

2. 创建新项目

在Android Studio中创建一个新的Android项目,并选择"Empty Activity"模板。在项目创建完成后,我们可以开始编写代码。

相机预览

首先,我们需要在应用中显示相机预览。Android提供了Camera类和CameraPreview类,可以实现这个功能。下面是一个简单的代码示例:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mHolder = getHolder();
        mHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (mHolder.getSurface() == null) {
            return;
        }

        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
        }

        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 释放相机资源
        mCamera.release();
    }
}

以上代码定义了一个CameraPreview类,继承自SurfaceView,其作用是在界面上显示相机预览。在surfaceCreated方法中,我们将相机与预览界面绑定,并开始预览。在surfaceChanged方法中,我们监听界面尺寸变化事件,停止当前预览,并重新设置预览界面并开始预览。在surfaceDestroyed方法中,我们释放相机资源。

拍摄横版照片

要实现拍摄横版照片的功能,我们需要在应用中添加一个按钮,当点击按钮时调用相机拍摄。下面是一个简单的代码示例:

public class MainActivity extends AppCompatActivity {
    private Camera mCamera;
    private CameraPreview mPreview;

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

        // 创建相机实例
        mCamera = getCameraInstance();

        // 创建相机预览
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout previewLayout = findViewById(R.id.camera_preview);
        previewLayout.addView(mPreview);

        // 添加拍照按钮点击事件
        Button captureButton = findViewById(R.id.button_capture);
        captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 拍照
                mCamera.takePicture(null, null, mPicture);
            }
        });
    }

    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // 保存照片到文件
            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            if (pictureFile == null){
                Log.d(TAG, "Error creating media file, check storage permissions.");
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.d(TAG, "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d(TAG, "Error accessing file: " + e.getMessage());