Camera1实现预览并自动获取图片(再次封装)

清单文件中添加权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!-- 闪光灯权限 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />

Camera1的封装:

 


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.bhyf.bhyfsdk.config.ImageInfo;
import com.bhyf.bhyfsdk.config.ImageStack;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
    private final static String TAG = "CameraSurfaceView";
    private SurfaceHolder surfaceHolder;
    private int mCameraIndex = 0;
    private Camera mCamera;
    private int mRotatePre = 0;
    private int mRotatePic = 0;
    private int mWidth = 0;
    private int mHeight = 0;

    private onPreviewChangedListener mOnPreviewChangedListener = null;
    private ImageStack imgStack = null;

    public static final int DEFAULT_CAMERA_IMAGE_WIDTH = 320;
    public static final int DEFAULT_CAMERA_IMAGE_HEIGHT = 240;
    public static final int DEFAULT_CAMERA_IMAGE_ROTATE = 90;
    public static final int DEFAULT_CAMERA_PRE_ROTATE = 90;

    public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 打开 cameraId = 1 的摄像头
     * 预览画面默认是横屏的,需要旋转90度
     */
    public void openCamera() {

        openCamera(1, DEFAULT_CAMERA_PRE_ROTATE, 
                DEFAULT_CAMERA_IMAGE_ROTATE,DEFAULT_CAMERA_IMAGE_WIDTH, DEFAULT_CAMERA_IMAGE_HEIGHT);

    }

    /**
     * 打开摄像头
     *
     * @param cameraId          摄像头序号
     * @param rotatePre         预览画面旋转角度
     * @param rotatePic         获取到的图片旋转角度
     * @param cameraImageWidth  图像preview宽度
     * @param cameraImageHeight 图像preview高度
     */
    public void openCamera(int cameraId, int rotatePre, int rotatePic,  int cameraImageWidth, int cameraImageHeight) {

        log("开始 打开摄像头--------");

        int mNumberOfCameras = Camera.getNumberOfCameras();
        log(" mNumberOfCameras:  " + mNumberOfCameras);

        if (mNumberOfCameras > cameraId) {
            initCameraView(cameraId, rotatePre, rotatePic,cameraImageWidth, cameraImageHeight);
        }
    }


    /**
     * @param cameraIndex 摄像头序号
     * @param rotatePre   预览画面旋转角度
     * @param rotatePic   获取到的图片旋转角度
     * @param width       图像preview宽度
     * @param height      图像preview高度
     */
    private void initCameraView(int cameraIndex, int rotatePre, int rotatePic, int width, int height) {
        log(String.format("CameraView initCameraView() cameraIndex:%d rotate:%d width:%d height:%d", cameraIndex, rotatePre, width, height));
        surfaceHolder = this.getHolder();
        surfaceHolder.addCallback(this);
        mCameraIndex = cameraIndex;
        mRotatePre = rotatePre;
        mRotatePic = rotatePic;
        mWidth = width;
        mHeight = height;
        imgStack = new ImageStack(mWidth, mHeight);
    }


    /**
     * 初始化SurfaceView时调用一次,另外更改surface或者onpause->onresume时调用
     */
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        log("CameraView surfaceChanged()");
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            // 选择合适的图片尺寸,必须是手机支持的尺寸
            /*
            List<Camera.Size> sizeList = parameters.getSupportedPictureSizes();
            // 如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择
            if (sizeList.size() > 1) {
            	int w = 0;
            	int h = 0;
                for (int j = 0; j < sizeList.size(); j++) {
                    Camera.Size size = sizeList.get(j);
                    w = size.width;
                    h = size.height;
                    log("w:" + w + " h:" + h);
                }
            }
            */
            //设置照片的大小
            log("setPictureSize mWidth:" + mWidth + " mHeight:" + mHeight);
            parameters.setPreviewSize(mWidth, mHeight);
            parameters.setPictureSize(mWidth, mHeight);
            parameters.setPreviewFpsRange(10, 20);
            try {
                mCamera.setParameters(parameters);
            } catch (RuntimeException ex) {
                ex.printStackTrace();
            }
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.setPreviewCallback(this);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //调用相机预览功能
            mCamera.startPreview();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        log("CameraView surfaceCreated()");
        if (null == mCamera) {
            //Camera.open()方法说明:2.3以后支持多摄像头,所以开启前可以通过getNumberOfCameras先获取摄像头数目,
            // 再通过 getCameraInfo得到需要开启的摄像头id,然后传入Open函数开启摄像头,
            // 假如摄像头开启成功则返回一个Camera对象
            try {
                mCamera = Camera.open(mCameraIndex);
                //预览画面默认是横屏的,需要旋转90度
                mCamera.setDisplayOrientation(mRotatePre);
            } catch (Exception e) {
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        log("CameraView surfaceDestroyed()");
        if (null != mCamera) {
            try {
                mCamera.setPreviewDisplay(null);
                mCamera.setPreviewCallback(null);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //停止预览
            mCamera.stopPreview();
            //释放相机资源
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        boolean isPreview = false;
        if (data != null) {
            isPreview = true;
            if (imgStack != null) {
                //log("imgStack.pushImageInfo() mCameraIndex:" + mCameraIndex);
                imgStack.pushImageInfo(data, System.currentTimeMillis());
            }
        }

        onPreviewChanged(isPreview);

    }

    public void setOnPreviewChangedListener(onPreviewChangedListener mPreviewChangedListener) {
        this.mOnPreviewChangedListener = mPreviewChangedListener;
    }

    public interface onPreviewChangedListener {
        void onPreviewChanged(Bitmap bitmap);
    }

    private void log(String msg) {
        Log.d(TAG, msg);
    }

    private static boolean isDisplay = false;

    public void cameraResume() {
        // TODO Auto-generated method stub
        isDisplay = true;
        if (faceDetectTask != null) {
            faceDetectTask.setStop(false);
        }

    }

    public void cameraPause() {
        // TODO Auto-generated method stub
        isDisplay = false;
        if (faceDetectTask != null) {
            faceDetectTask.setStop(true);
        }

    }


    public void cameraDestory() {
        // TODO Auto-generated method stub
        if (faceDetectTask != null) {
            faceDetectTask.setStop(true);
            faceDetectTask.cancel(true);
            faceDetectTask = null;
        }
    }


    public void onPreviewChanged(boolean isPreview) {
        if (isDisplay && isPreview && !isRunning) {
            log("====onPreviewChanged() isPreview:" + isPreview);
            startRecognizeUser();
        }
    }


    private boolean isRunning = false;
    private FaceDetectTask faceDetectTask;

    public void startRecognizeUser() {
        log("startRecognizeUser isRunning: " + isRunning);
        if (!isRunning) {
            isRunning = true;
            log("startRecognizeUser isRunning: " + isRunning);

            if (imgStack != null) {
                // 清空缓存记录
                imgStack.clearAll();
            }

            if (faceDetectTask != null) {
                faceDetectTask.setStop(true);
                faceDetectTask = null;
            }
            faceDetectTask = new FaceDetectTask();
            faceDetectTask.setStop(false);
            faceDetectTask.execute();
        }
    }

    /**
     * 定义一个类,让其继承AsyncTask这个类
     */
    class FaceDetectTask extends AsyncTask<Void, Rect, Void> {

        private boolean isStop = false;

        public void setStop(boolean isStop) {
            this.isStop = isStop;
        }

        @Override
        protected Void doInBackground(Void... voids) {

            ImageInfo imgInfo = null;

            while (!isStop && isRunning) {

                if (imgStack != null)
                    imgInfo = imgStack.pullImageInfo();

                if (!isStop && isRunning && imgInfo != null && imgInfo.isNew()) {

                    Log.d(TAG,"doInBackground imgInfo.isNew(): " + imgInfo.isNew());
                    byte[] data = imgInfo.getData();

                    Log.d(TAG, data.toString());

                    Bitmap bitmapCamera = null;

                    if (null != data) {
                        //获取图片
                        ByteArrayOutputStream baos;
                        byte[] rawImage;
                        BitmapFactory.Options newOpts = new BitmapFactory.Options();
                        newOpts.inJustDecodeBounds = true;
                        YuvImage yuvimage = new YuvImage(
                                data,
                                ImageFormat.NV21,
                                mWidth,
                                mHeight,
                                null);
                        baos = new ByteArrayOutputStream();
                        yuvimage.compressToJpeg(new Rect(0, 0, mWidth, mHeight), 100, baos);// 80--JPG图片的质量[0-100],100最高
                        rawImage = baos.toByteArray();
                        //将rawImage转换成bitmap
                        BitmapFactory.Options options = new BitmapFactory.Options();
                        options.inPreferredConfig = Bitmap.Config.RGB_565;
                        //获取到图片
                        Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);

                        //摄像头拍出来的图片,默认是横着的,所以需要对图片进行旋转
                        if (bitmap != null) {
                            Matrix matrix = new Matrix();
                            matrix.postRotate((float) mRotatePic);
                            bitmapCamera = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
                        }

                        Log.d(TAG, "dealData 获取到的图片 bitmapCamera --> " + bitmapCamera);

                    }

                    if (bitmapCamera != null) {
                        // TODO 获取到图片
                        Message message = Message.obtain();
                        message.what = 12341;
                        message.obj = bitmapCamera;
                        handler.sendMessage(message);
                        
                    }
                }
            }

            return null;
        }

    }
    
    

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {

            if (msg.what == 12341) {

                Bitmap bitmap = (Bitmap) msg.obj;

                if (mOnPreviewChangedListener != null) {
                    
                    mOnPreviewChangedListener.onPreviewChanged(bitmap);
                }
            }
        }
    };

}

 

Activity代码:

 

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.ImageView;
import android.widget.Toast;

import com.bhyf.bhyf_demo.R;
import com.bhyf.bhyf_demo.view.CameraSurfaceView;


/**
 * 获取相机图片
 */
public class Camera2Activity extends Activity implements CameraSurfaceView.onPreviewChangedListener {



    private CameraSurfaceView surfaceView;
    private ImageView image;

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


        surfaceView = (CameraSurfaceView) findViewById(R.id.surfaceView);
        surfaceView.setOnPreviewChangedListener(this);

        image = findViewById(R.id.image);

        if (!checkedHardware(this)) {
            Toast.makeText(this, "no camera", Toast.LENGTH_LONG).show();
        }else {
            surfaceView.openCamera();
        }
    }
    

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        surfaceView.cameraResume();

    }


    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        surfaceView.cameraPause();

    }


    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub

        surfaceView.cameraDestory();

        super.onDestroy();
    }


    @SuppressWarnings("unused")
    private boolean checkedHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            return true;
        }
        return false;
    }


    @Override
    public void onPreviewChanged(Bitmap bitmap) {
        image.setImageBitmap(bitmap);
    }
}

 

 

布局文件:

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#fff"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/layout"
        android:layout_below="@+id/tv_face"
        android:layout_centerInParent="true"
        android:layout_marginTop="30dp"
        android:layout_width="420dp"
        android:layout_height="540dp">

        <com.kris.kris_demo.view.CameraSurfaceView
            android:id="@+id/surfaceView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>


    </RelativeLayout>

    <ImageView
        android:id="@+id/image"
        android:layout_width="400dp"
        android:layout_height="400dp"/>



</RelativeLayout>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值