安卓高级8 SurfaceView案例二 自定义相机

效果:(由于不好录屏所以文字描述)
定一个SurfaceView 下方有几个按钮,点击确定可以拍照保存取消.
并且SurfaceView实时显示相机内容

package qianfeng.com.customcamera;

import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private SurfaceView surfaceView;
    private SurfaceHolder holder;
    private Camera camera;
    private byte[] bitmap_byte;
    private int flag = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceView = (SurfaceView) findViewById(R.id.camera_sv);

        holder = surfaceView.getHolder();
        //设置 Holder 的类型 表示内容 表示内容为空由其他提供
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.addCallback(this);


//        实例化Camera     参数表示   0:  后置摄像头  1:前置摄像头
        camera = Camera.open(flag);
        // 按照顺时针方向旋转90度
        camera.setDisplayOrientation(90);
//         获取一共有多少个摄像头
//        Camera.getNumberOfCameras();
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.take_bt:
                /*
                参数1: 捕捉画面回调
                参数2:原声图片回调
                参数3: 处理过后的图片回调
                 */
                camera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        //停止预览
                        camera.stopPreview();
                        // 记录图片数据
                        bitmap_byte = data;
                    }
                });
                break;
            case R.id.cancel_bt:
                //取消
                bitmap_byte = null;
                // 开启预览
                camera.startPreview();
                break;
            case R.id.save_bt:
                // 保存
                saveToSd();
                break;
            case R.id.change_bt:
                // 切换前后摄像头
                //先释放
                camera.stopPreview();
                camera.release();
                camera = null;


                // 切换摄像头标记     与当前的标记相反即可
                if (flag == 1)
                    flag = 0;
                else if (flag == 0)
                    flag = 1;

                // 重新开启相机
                camera = Camera.open(flag);
                camera.setDisplayOrientation(90);
                try {
                    camera.setPreviewDisplay(holder);
                    camera.startPreview();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    // 保存图片到SD卡
    private void saveToSd() {
        String filPath = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            filPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "xixi.png";
        }
        try {
            FileOutputStream out = new FileOutputStream(filPath);
            out.write(bitmap_byte, 0, bitmap_byte.length);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (camera != null) {
            try {
                //  提供预览画面
                camera.setPreviewDisplay(holder);
                // 开启预览
                camera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (camera != null) {
            // 销毁的时候停止预览
            camera.stopPreview();
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="qianfeng.com.customcamera.MainActivity">

    <SurfaceView
        android:id="@+id/camera_sv"
        android:layout_width="match_parent"
        android:layout_height="400dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/take_bt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="拍照" />

        <Button
            android:id="@+id/cancel_bt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="取消" />

        <Button
            android:id="@+id/save_bt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="保存" />

        <Button
            android:id="@+id/change_bt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="切换" />


    </LinearLayout>
</LinearLayout>
原文地址:https://www.cnblogs.com/muyuge/p/6152131.html