自定义相机,使用前置摄像头实现自拍

通过Camera.open()获取相机,实现自定义自拍功能。

demo比较简单,直接上代码:

Activity


public class MainActivity extends AppCompatActivity {

    SurfaceView sView;
    SurfaceHolder surfaceHodler;
    int screenWidth, screenHeight;
    // 定义系统所用的照相机
    Camera camera;
    // 是否存在预览中
    boolean isPreview = false;
    private String filepath = "";//照片保存路径

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


        // 获取窗口管理器
        WindowManager wm = getWindowManager();
        Display display = wm.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        // 获取屏幕的宽和高
        display.getMetrics(metrics);
        screenWidth = metrics.widthPixels;
        screenHeight = metrics.heightPixels;
        sView = (SurfaceView) findViewById(R.id.sView);
        // 设置surface不需要自己的维护缓存区
        sView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // 获得SurfaceView的SurfaceHolder
        surfaceHodler = sView.getHolder();
        // 为srfaceHolder添加一个回调监听器
        surfaceHodler.addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceDestroyed(SurfaceHolder arg0) {
                // 如果camera不为null,释放摄像头
                System.out.println("释放摄像头");
                if (camera != null) {
                    if (isPreview)
                        camera.stopPreview();
                    camera.release();
                    camera = null;
                    isPreview = false;
                }
            }

            @Override
            public void surfaceCreated(SurfaceHolder arg0) {
                System.out.println("打开摄像头");
                // 打开摄像头
                initCamera();
            }

            @Override
            public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
                                       int arg3) {
                System.out.println("摄像头改变");
            }
        });

    }

    public void capture(View source) {
        sView.setVisibility(View.VISIBLE);
    }

    private void initCamera() {
        if (!isPreview) {
            // 此处默认打开后置摄像头
            // 通过传入参数可以打开前置摄像头
            camera = openFrontFacingCameraGingerbread();
        }
        if (!isPreview && camera != null) {
            Camera.Parameters parameters = camera.getParameters();
            // 设置预览照片的大小
            parameters.setPreviewSize(screenWidth, screenHeight);
            // 设置预览照片时每秒显示多少帧的最小值和最大值
            parameters.setPreviewFpsRange(4, 10);
            // 设置照片的格式
            parameters.setPictureFormat(ImageFormat.JPEG);
            parameters.setPreviewSize(800, 480);//图片大小
            // 设置JPG照片的质量
            parameters.set("jpeg-quality", 100);
            // 设置照片的大小
            parameters.setPictureSize(screenWidth, screenHeight);
            // 通过SurfaceView显示取景画面
            try {
                camera.setPreviewDisplay(surfaceHodler);
                // 系统相机默认是横屏的,我们要旋转90°
                camera.setDisplayOrientation(90);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 开始预览
            camera.startPreview();
            isPreview = true;

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (camera != null) {
                        System.out.println("控制摄像头自动对焦后才拍摄");
                        // 控制摄像头自动对焦后才拍摄
                        //camera.autoFocus(autoFocusCallback);
                        //关闭声音
                        setCameraSound(true);
                        camera.takePicture(new Camera.ShutterCallback() {

                            @Override
                            public void onShutter() {
                                // 按下快门瞬间会执行此处代码
                            }
                        }, new Camera.PictureCallback() {

                            @Override
                            public void onPictureTaken(byte[] arg0, Camera arg1) {
                                // 此处代码可以决定是否需要保存原始照片信息
                            }
                        }, jpeg);
                    }
                }
            }, 1000);
        }
    }

    private Camera openFrontFacingCameraGingerbread() {
        int cameraCount = 0;
        Camera cam = null;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();
        System.out.println("cameraCount = "+cameraCount);
        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
            Camera.getCameraInfo(camIdx, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                try {
                    cam = Camera.open(camIdx);
                } catch (RuntimeException e) {
                    Log.e("", "Camera failed to open: " + e.getLocalizedMessage());
                }
            }
        }
        System.out.println("获取摄像头");
        if (cam == null)
            System.out.println("摄像头获取失败");
        return cam;
    }


    Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean arg0, Camera arg1) {
            if (arg0) {
                //关闭声音
                setCameraSound(true);
                // takePicture()方法需要传入三个监听参数
                // 第一个监听器;当用户按下快门时激发该监听器
                // 第二个监听器;当相机获取原始照片时激发该监听器
                // 第三个监听器;当相机获取JPG照片时激发该监听器
                System.out.println("拍照");
                camera.takePicture(new Camera.ShutterCallback() {

                    @Override
                    public void onShutter() {
                        // 按下快门瞬间会执行此处代码
                    }
                }, new Camera.PictureCallback() {

                    @Override
                    public void onPictureTaken(byte[] arg0, Camera arg1) {
                        // 此处代码可以决定是否需要保存原始照片信息
                    }
                }, jpeg);

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                      //  sView.setVisibility(View.GONE);
                        //
                    }
                }, 1000);

            } else {
                System.out.println("对焦失败,不拍照");
            }
        }
    };


    //创建jpeg图片回调数据对象
    Camera.PictureCallback jpeg = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // TODO Auto-generated method stub
            try {
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                // 创建一个位于SD卡上的文件
                File file = new File(Environment.getExternalStorageDirectory() + File.separator + "aaa");
                if (!file.exists()) {
                    file.mkdir();
                }
                file = new File(file, System.currentTimeMillis() + ".jpg");
                FileOutputStream fileOutStream = null;
                try {
                    fileOutStream = new FileOutputStream(file);
                    //把位图输出到指定的文件中
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutStream);
                    fileOutStream.close();
                } catch (IOException io) {
                    io.printStackTrace();
                }


                camera.stopPreview();//关闭预览 处理数据
                camera.startPreview();//数据处理完后继续开始预览
                bitmap.recycle();//回收bitmap空间
                isPreview = true;
                //关闭预览框,回复声音
                sView.setVisibility(View.GONE);
                setCameraSound(false);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

    private void setCameraSound(final boolean isSound) {
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
                        audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, isSound);
                    }
                }
        ).start();
    }
}

XML


<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.jin.activity.MainActivity">

    <SurfaceView
        android:id="@+id/sView"
        android:layout_width="80dp"
        android:layout_height="100dp"
        android:layout_alignParentRight="true"
        android:visibility="gone">SurfaceView>

    <Button
        android:id="@+id/take"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="capture"
        android:text="开门">Button>

RelativeLayout>

注:
经过测试发现7.0以下手机没问题,而7.0系统手机在Camera.open()出现Camera failed to open: Fail to connect to camera service,就是获取不到相机服务无法打开相机,需要手动在手机设置里面打开相机权限,即可正常使用。因此可以加一个判断:

//判断系统版本大于23,即247.0)和以上版本提示打开权限
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {

        }

你可能感兴趣的:(android,摄像头,自拍,Camera)