android简单的自定义相机

来源:互联网 发布:西安天睿软件 编辑:程序博客网 时间:2024/04/29 21:27

android简单的自定义相机

  • 项目需求

    公司手环有一个功能是点击手环(手环发送命令给手机)手机自动拍照,如果是调用系统相机不知道代码中怎么自动点击拍照键(毕竟系统功能全,知道的同学还望告知一二),所以只好自己写个最简单的相机了,此相机只拍照没其他功能(技术太菜了其他不会整),虽然功能简单,坑也不少啊!

  • 代码

public class CameraActivity extends BaseActivity implements SurfaceHolder.Callback, View.OnClickListener {    @BindView(R.id.surfaceView)    SurfaceView surfaceView;    //照片缩略图    @BindView(R.id.camera_photo)    FullPhotoView cameraPhoto;    //闪光灯图片    @BindView(R.id.flash)    ImageView flash;    //导航栏    @BindView(R.id.common_top_bar)    CommonTopBar mCommonTopBar;    private SurfaceHolder mHolder;    private int mCameraId = 0;    private Camera mCamera;    //屏幕宽高    private int screenWidth;    //延迟时间    private boolean isview = false;    private int picHeight;    //闪光灯图标    private static final int[] FLASH_ICONS = {            R.drawable.ic_flash_off,            R.drawable.ic_flash_on,            R.drawable.ic_flash_auto,    };    //闪光灯模式 0:关闭 1: 开启 2: 自动    private int light_num = 2;    private static final String[] FLASH_OPTIONS = {            Camera.Parameters.FLASH_MODE_OFF,            Camera.Parameters.FLASH_MODE_TORCH,            Camera.Parameters.FLASH_MODE_AUTO,    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_camera);        //状态栏工具        StatusBarUtil.setColor(this, getResources().getColor(R.color.transparent_22000000), 0);        initView();        EventBus.getDefault().register(this);    }    private void initView() {        mHolder = surfaceView.getHolder();        mHolder.addCallback(this);        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();        screenWidth = dm.widthPixels;    }    @Override    public void initParams() {        super.initParams();        mCommonTopBar.setUpNavigateMode();        mCommonTopBar.setTitle(R.string.activity_camera);        mCommonTopBar.setUpImgOption(R.drawable.ic_party_mode_white_24dp, new View.OnClickListener() {            @Override            public void onClick(View view) {                switchCamera();            }        });    }    @OnClick({R.id.camera_take,  R.id.flash})    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.camera_take:                takePhoto();                break;            //闪光灯            case R.id.flash:                if (mCameraId == 1) { //前置                    Toast.makeText(mContext, "请切换为后置摄像头开启闪光灯", Toast.LENGTH_SHORT).show();                    return;                }                Camera.Parameters parameters = mCamera.getParameters();                light_num = (light_num + 1) % 3;                parameters.setFlashMode(FLASH_OPTIONS[light_num]);                flash.setImageResource(FLASH_ICONS[light_num]);                mCamera.setParameters(parameters);                break;        }    }    //前后相机切换    public void switchCamera() {        releaseCamera();        mCameraId = (mCameraId + 1) % mCamera.getNumberOfCameras();        mCamera = getCamera(mCameraId);        if (mHolder != null) {            startPreview(mCamera, mHolder);        }    }    @Override    protected void onResume() {        super.onResume();        if (mCamera == null) {            mCamera = getCamera(mCameraId);            if (mHolder != null) {                startPreview(mCamera, mHolder);            }        }    }    @Override    protected void onStop() {        super.onStop();        releaseCamera();    }    @Override    protected void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }    //获取相机    private Camera getCamera(int id) {        Camera camera = null;        try {            camera = Camera.open(id);        } catch (Exception e) {        }        return camera;    }    //开始预览    private void startPreview(Camera camera, SurfaceHolder holder) {        try {            setCamera(camera);            camera.setPreviewDisplay(holder);            //亲测的一个方法 基本覆盖所有手机 将预览矫正            CameraUtil.getInstance().setCameraDisplayOrientation(this, mCameraId, camera);            camera.startPreview();            isview = true;        } catch (IOException e) {            e.printStackTrace();        }    }    private void takePhoto() {        if (isview) {            switch (light_num) {                case 0:                    //关闭                    CameraUtil.getInstance().turnLightOff(mCamera);                    break;                case 1:                    CameraUtil.getInstance().turnLightOn(mCamera);                    break;                case 2:                    //自动                    CameraUtil.getInstance().turnLightAuto(mCamera);                    break;            }            takePicture();            isview = false;        }    }    private void takePicture() {        mCamera.takePicture(null, null, new Camera.PictureCallback() {            @Override            public void onPictureTaken(byte[] data, Camera camera) {                BleLog.e("onPictureTaken:" + data.length);                isview = false;                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                //旋转方向                Matrix matrix = new Matrix();                matrix.preRotate(90);                if (mCameraId != 0) {                    matrix.preRotate(180);                }                Bitmap rotaBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);                Bitmap bit = GetRoundedCornerBitmap(Bitmap.createScaledBitmap(rotaBitmap, cameraPhoto.getWidth(), cameraPhoto.getHeight(), true));                cameraPhoto.setImageBitmap(bit);                final Bitmap saveBitmap = CameraUtil.getInstance().setTakePicktrueOrientation(mCameraId, bitmap);                new Handler().post(new Runnable() {                    @Override                    public void run() {                        cameraPhoto.setUri(Util.savePic(mContext, saveBitmap));                    }                });                startPreview(mCamera, mHolder);            }        });    }    //转圆角矩形    public Bitmap GetRoundedCornerBitmap(Bitmap bitmap) {        try {            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(output);            final Paint paint = new Paint();            final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());            final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()));            final float roundPx = 15;            paint.setAntiAlias(true);            canvas.drawARGB(0, 0, 0, 0);            paint.setColor(Color.BLACK);            canvas.drawRoundRect(rectF, roundPx, roundPx, paint);            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));            final Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());            canvas.drawBitmap(bitmap, src, rect, paint);            return output;        } catch (Exception e) {            return bitmap;        }    }    //相机参数设置    private void setCamera(Camera camera) {        Camera.Parameters parameters = camera.getParameters();        List<String> focusModes = parameters.getSupportedFocusModes();        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {            // Autofocus mode is supported 自动对焦            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);        }        //这里第三个参数为最小尺寸 getPropPreviewSize方法会对从最小尺寸开始升序排列 取出所有支持尺寸的最小尺寸        Camera.Size previewSize = CameraUtil.getInstance().getPropSizeForHeight(parameters.getSupportedPreviewSizes(), screenWidth);        parameters.setPreviewSize(previewSize.width, previewSize.height);        Camera.Size pictrueSize = CameraUtil.getInstance().getPropSizeForHeight(parameters.getSupportedPictureSizes(), screenWidth);        parameters.setPictureSize(pictrueSize.width, pictrueSize.height);        camera.setParameters(parameters);        /**         * 设置surfaceView的尺寸 因为camera默认是横屏,所以取得支持尺寸也都是横屏的尺寸         * 我们在startPreview方法里面把它矫正了过来,但是这里我们设置设置surfaceView的尺寸的时候要注意 previewSize.height<previewSize.width         * previewSize.width才是surfaceView的高度         * 一般相机都是屏幕的宽度 这里设置为屏幕宽度 高度自适应 你也可以设置自己想要的大小         */        picHeight = screenWidth * previewSize.width / previewSize.height;        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(screenWidth, picHeight);        //这里当然可以设置拍照位置 比如居中 我这里就置顶了        //params.gravity = Gravity.CENTER;        surfaceView.setLayoutParams(params);    }    //释放资源    private void releaseCamera() {        if (mCamera != null) {            mCamera.setPreviewCallback(null);            mCamera.stopPreview();            mCamera.release();            mCamera = null;        }    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        startPreview(mCamera, holder);    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        mCamera.stopPreview();        startPreview(mCamera, holder);    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        releaseCamera();    }    //接收到手环的拍照指令    @Subscribe(threadMode = ThreadMode.MAIN)    public void getBleData(byte[] data) {        if (data[0] == 0x07 && data[2] == 0x06) {            takePhoto();        }    }}
public class CameraUtil {    private static CameraUtil myCamPara = null;    private CameraUtil() {    }    public static CameraUtil getInstance() {        if (myCamPara == null) {            myCamPara = new CameraUtil();        }        return myCamPara;    }    //保证预览方向正确    public void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {        Camera.CameraInfo info = new Camera.CameraInfo();        Camera.getCameraInfo(cameraId, info);        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();        int degrees = 0;        switch (rotation) {            case Surface.ROTATION_0: degrees = 0; break;            case Surface.ROTATION_90: degrees = 90; break;            case Surface.ROTATION_180: degrees = 180; break;            case Surface.ROTATION_270: degrees = 270; break;        }        int result;        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {            result = (info.orientation + degrees) % 360;            result = (360 - result) % 360;        } else {            result = (info.orientation - degrees + 360) % 360;        }        camera.setDisplayOrientation(result);    }    public Bitmap setTakePicktrueOrientation(int id, Bitmap bitmap) {        Camera.CameraInfo info = new Camera.CameraInfo();        Camera.getCameraInfo(id, info);        bitmap = rotaingImageView(id, info.orientation, bitmap);        return bitmap;    }    /**     * 把相机拍照返回照片转正     * @param angle 旋转角度     * @return bitmap 图片     */    public Bitmap rotaingImageView(int id, int angle, Bitmap bitmap) {        //旋转图片 动作        Matrix matrix = new Matrix();        matrix.postRotate(angle);        //加入翻转 把相机拍照返回照片转正        if (id == 1) {            matrix.postScale(-1, 1);        }        // 创建新的图片        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,                bitmap.getWidth(), bitmap.getHeight(), matrix, true);        return resizedBitmap;    }    /**     * 获取所有支持的返回视频尺寸     */    public Size getPropSizeForHeight(List<Size> list, int minHeight) {        Collections.sort(list, new CameraAscendSizeComparatorForHeight());        int i = 0;        for (Size s : list) {            if ((s.height >= minHeight)) {                break;            }            i++;        }        if (i == list.size()) {            i = 0;//如果没找到,就选最小的size        }        return list.get(i);    }    //升序 按照高度    public class CameraAscendSizeComparatorForHeight implements Comparator<Size> {        public int compare(Size lhs, Size rhs) {            if (lhs.height == rhs.height) {                return 0;            } else if (lhs.height > rhs.height) {                return 1;            } else {                return -1;            }        }    }    //打开闪关灯    public void turnLightOn(Camera mCamera) {        if (mCamera == null) {            return;        }        Camera.Parameters parameters = mCamera.getParameters();        if (parameters == null) {            return;        }        List<String> flashModes = parameters.getSupportedFlashModes();        if (flashModes == null) {            return;        }        String flashMode = parameters.getFlashMode();        if (!Camera.Parameters.FLASH_MODE_ON.equals(flashMode)) {            if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);                mCamera.setParameters(parameters);            }        }    }    //自动模式闪光灯    public void turnLightAuto(Camera mCamera) {        if (mCamera == null) {            return;        }        Camera.Parameters parameters = mCamera.getParameters();        if (parameters == null) {            return;        }        List<String> flashModes = parameters.getSupportedFlashModes();        if (flashModes == null) {            return;        }        String flashMode = parameters.getFlashMode();        if (!Camera.Parameters.FLASH_MODE_AUTO.equals(flashMode)) {            if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);                mCamera.setParameters(parameters);            }        }    }    // 关闭闪光灯    public void turnLightOff(Camera mCamera) {        if (mCamera == null) {            return;        }        Camera.Parameters parameters = mCamera.getParameters();        if (parameters == null) {            return;        }        List<String> flashModes = parameters.getSupportedFlashModes();        String flashMode = parameters.getFlashMode();        if (flashModes == null) {            return;        }        if (!Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)) {            if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);                mCamera.setParameters(parameters);            }        }    }}
0 0