Android 自定义相机,横屏显示、纵屏显示只拍照矩形框中的图片大小

       最近公司项目有需要开发一个相机?要识别车牌号和VIN(车架号)要求如下:

1.要求扫描车牌号要竖屏显示。

2.要求扫描车架号要横屏显示。

       并且在扫描的时候要遮挡区域只显示中间的矩形扫描框,拍照完成后只显示矩形框的图片,然后将图片上传上去进行识别返回车牌信息和VIN信息。这里项目做完了做了一个Dome希望可以帮到大家。先上两张图:

横屏显示(图1)

 

 

竖屏显示(图2)

 

第一步:

package com.leict.custom.maskcamera.camera;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;

import com.leict.custom.maskcamera.utils.Utils;
import com.leict.custom.maskcamera.views.PlateSurfaceView;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class CameraPlateHelper {
    private final String TAG = CameraPlateHelper.class.getSimpleName();
    private boolean isPreview;
    private static CameraPlateHelper helper;
    private Camera camera;
    private ToneGenerator tone;
    private PlateSurfaceView surfaceView;
    /**
     * 分辨率
     */
    private Size resolution;

    /**
     * 照片质量
     */
    private int picQuality = 100;

    /**
     * 照片尺寸
     */
    private Size pictureSize;
    /**
     * 上下文
     */
    private Context mContext;
    /**
     * 闪光灯模式(default:自动)
     */
    private String flashStatus = Parameters.FLASH_MODE_AUTO;

    public enum Flashlight {
        AUTO, ON, OFF
    }

    private CameraPlateHelper(Context context) {
        this.mContext = context;
    }

    public static CameraPlateHelper getInstance(Context context) {
        if (helper == null) {
            synchronized (CameraPlateHelper.class) {
                if (helper == null) {
                    helper = new CameraPlateHelper(context.getApplicationContext());
                }
            }
        }
        return helper;
    }

    /**
     * 设置闪光灯模式
     *
     * @param status
     * @return
     */
    public CameraPlateHelper setFlashState(Flashlight status) {
        switch (status) {
            case AUTO:
                this.flashStatus = Parameters.FLASH_MODE_AUTO;
                break;
            case ON:
                this.flashStatus = Parameters.FLASH_MODE_ON;
                break;
            case OFF:
                this.flashStatus = Parameters.FLASH_MODE_OFF;
                break;
            default:
                this.flashStatus = Parameters.FLASH_MODE_AUTO;
        }
        return helper;
    }

    public CameraPlateHelper setMaskSurfaceView(PlateSurfaceView surfaceView) {
        this.surfaceView = surfaceView;
        return helper;
    }

    /**
     * 获取Camera对象
     *
     * @return
     */
    private Camera getCamera() {
        Camera camera;
        try {
            camera = Camera.open();
        } catch (Exception e) {
            camera = null;
            e.printStackTrace();
        }
        return camera;
    }

    /**
     * 打开相机并开启预览
     *
     * @param holder       SurfaceHolder
     * @param format       图片格式
     * @param width        SurfaceView宽度
     * @param height       SurfaceView高度
     * @param screenWidth  屏幕宽度
     * @param screenHeight 屏幕高度
     */
    public void openCamera(SurfaceHolder holder, int format, int width, int height, int screenWidth, int screenHeight) {
        if (this.camera != null) {
            this.camera.release();
        }
        this.camera = getCamera();
        this.setParameter(holder, format, width, height, screenWidth, screenHeight);
        this.startPreview();
    }

    /**
     * 照相
     */
    public void tackPicture(final TakePhotoCallback callback) {
        this.camera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean flag, Camera camera) {
                camera.takePicture(new Camera.ShutterCallback() {
                    @Override
                    public void onShutter() {
                        if (tone == null) {
                            //发出提示用户的声音
                            tone = new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOLUME);
                        }
                        tone.startTone(ToneGenerator.TONE_PROP_BEEP2);
                    }
                }, null, new PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        String filepath = savePicture(data);
                        boolean success = false;
                        if (filepath != null) {
                            success = true;
                        }
                        stopPreview();
                        callback.onCapture(success, filepath);
                    }
                });
            }
        });
    }

    /**
     * 裁剪并保存照片
     *
     * @param data
     * @return
     */
    private String savePicture(byte[] data) {
        String filePath = Environment.getExternalStorageDirectory() + "/cbx/vehicle.jpg";
        Bitmap bitmap = cutPicture(data);
        try {
            int length = filePath.length();
            String strPath = filePath.substring(0, filePath.indexOf("v"));
            String strName = filePath.substring(filePath.indexOf("v"), length);
            if (Utils.isExist(strPath, strName)) {
                File imgFile = new File(filePath);
                FileOutputStream fos = new FileOutputStream(imgFile);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                fos.close();
                bos.flush();
                bos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }


    /**
     * 初始化相机参数
     *
     * @param holder       SurfaceHolder
     * @param format       图片格式
     * @param width        SurfaceView宽度
     * @param height       SurfaceView高度
     * @param screenWidth  屏幕宽度
     * @param screenHeight 屏幕高度
     */
    private void setParameter(SurfaceHolder holder, int format, int width, int height, int screenWidth, int screenHeight) {
        try {
            Parameters p = this.camera.getParameters();
            this.camera.setPreviewDisplay(holder);
            if (width > height) {
                //横屏
                this.camera.setDisplayOrientation(0);
            } else {
                //竖屏
                this.camera.setDisplayOrientation(90);
            }
            //照片质量
            p.set("jpeg-quality", picQuality);
            //设置照片格式
            p.setPictureFormat(ImageFormat.JPEG);
            //设置闪光灯
            p.setFlashMode(flashStatus);
            //设置最佳预览尺寸
            List previewSizes = p.getSupportedPreviewSizes();
            //设置预览分辨率
            if (this.resolution == null) {
                this.resolution = this.getOptimalPreviewSize(previewSizes, width, height);
            }
            try {
                p.setPreviewSize(this.resolution.width, this.resolution.height);
            } catch (Exception e) {
                Log.e(TAG, "不支持的预览分辨率: " + this.resolution.width + " × " + this.resolution.height);
            }
            //设置照片尺寸
            if (this.pictureSize == null) {
                List pictureSizes = p.getSupportedPictureSizes();
                this.setPicutreSize(pictureSizes, screenWidth, screenHeight);
            }
            try {
                p.setPictureSize(this.pictureSize.width, this.pictureSize.height);
            } catch (Exception e) {
                Log.e(TAG, "不支持的照片尺寸: " + this.pictureSize.width + " × " + this.pictureSize.height);
            }
            this.camera.setParameters(p);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "相机参数设置错误");
        }
    }

    /**
     * 释放Camera
     */
    public void releaseCamera() {
        if (this.camera != null) {
            if (this.isPreview) {
                this.stopPreview();
            }
            this.camera.setPreviewCallback(null);
            this.isPreview = false;
            this.camera.release();
            this.camera = null;
        }
    }

    /**
     * 停止预览
     */
    private void stopPreview() {
        if (this.camera != null && this.isPreview) {
            this.camera.stopPreview();
            this.isPreview = false;
        }
    }

    /**
     * 开始预览
     */
    public void startPreview() {
        if (this.camera != null) {
            this.camera.startPreview();
            this.camera.autoFocus(null);
            this.isPreview = true;
        }
    }

    /**
     * 裁剪照片
     *
     * @param data
     * @return
     */
    private Bitmap cutPicture(byte[] data) {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        if (this.surfaceView.getWidth() < this.surfaceView.getHeight()) {
            //竖屏旋转照片
            Matrix matrix = new Matrix();
            matrix.reset();
            matrix.setRotate(90);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }
        if (this.surfaceView == null) {
            return bitmap;
        } else {
            int[] sizes = this.surfaceView.getMaskSize();
            if (sizes[0] == 0 || sizes[1] == 0) {
                return bitmap;
            }
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();
            int x = (w - sizes[0]) / 2;
            int y = (h - sizes[1]) / 2;
            Log.i("bitmap_w--------->>>", String.valueOf(w));
            Log.i("bitmap_h--------->>>", String.valueOf(h));
            Log.i("x--------->>>", String.valueOf(x));
            Log.i("y--------->>>", String.valueOf(y));
            Log.i("w--------->>>", String.valueOf(sizes[0]));
            Log.i("h--------->>>", String.valueOf(sizes[1]));
            //return Bitmap.createBitmap(bitmap, x, y, sizes[0], sizes[1]);
            return Bitmap.createBitmap(bitmap, 0, y - 30, w, sizes[0]);
        }
    }

    /**
     * 获取最佳预览尺寸
     */
    private Size getOptimalPreviewSize(List sizes, int width, int height) {
        final double ASPECT_TOLERANCE = 0.05;
        double targetRatio = (double) width / height;
        if (sizes == null)
            return null;
        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        int targetHeight = height;
        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double r = size.width * 1.0 / size.height * 1.0;
            if (r != 4 / 3 || r != 3 / 4 || r != 16 / 9 || r != 9 / 16) {
                continue;
            }
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    /**
     * 设置照片尺寸为最接近屏幕尺寸
     *
     * @param list
     * @return
     */
    private void setPicutreSize(List list, int screenWidth, int screenHeight) {
        int approach = Integer.MAX_VALUE;
        for (Size size : list) {
            int temp = Math.abs(size.width - screenWidth + size.height - screenHeight);
            if (approach > temp) {
                approach = temp;
                this.pictureSize = size;
            }
        }
    }
}

第二步:

package com.leict.custom.maskcamera.camera;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;

import com.leict.custom.maskcamera.utils.Utils;
import com.leict.custom.maskcamera.views.VinSurfaceView;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class CameraVinHelper {
    private final String TAG = CameraVinHelper.class.getSimpleName();
    private boolean isPreview;
    private static CameraVinHelper helper;
    private Camera camera;
    private ToneGenerator tone;
    private VinSurfaceView surfaceView;
    /**
     * 分辨率
     */
    private Camera.Size resolution;

    /**
     * 照片质量
     */
    private int picQuality = 100;

    /**
     * 照片尺寸
     */
    private Camera.Size pictureSize;
    /**
     * 上下文
     */
    private Context mContext;
    /**
     * 闪光灯模式(default:自动)
     */
    private String flashStatus = Camera.Parameters.FLASH_MODE_AUTO;

    public enum Flashlight {
        AUTO, ON, OFF
    }

    private CameraVinHelper(Context context) {
        this.mContext = context;
    }

    public static CameraVinHelper getInstance(Context context) {
        if (helper == null) {
            synchronized (CameraVinHelper.class) {
                if (helper == null) {
                    helper = new CameraVinHelper(context.getApplicationContext());
                }
            }
        }
        return helper;
    }

    /**
     * 设置闪光灯模式
     *
     * @param status
     * @return
     */
    public CameraVinHelper setFlashState(CameraPlateHelper.Flashlight status) {
        switch (status) {
            case AUTO:
                this.flashStatus = Camera.Parameters.FLASH_MODE_AUTO;
                break;
            case ON:
                this.flashStatus = Camera.Parameters.FLASH_MODE_ON;
                break;
            case OFF:
                this.flashStatus = Camera.Parameters.FLASH_MODE_OFF;
                break;
            default:
                this.flashStatus = Camera.Parameters.FLASH_MODE_AUTO;
        }
        return helper;
    }

    public CameraVinHelper setMaskSurfaceView(VinSurfaceView surfaceView) {
        this.surfaceView = surfaceView;
        return helper;
    }

    /**
     * 获取Camera对象
     *
     * @return
     */
    private Camera getCamera() {
        Camera camera;
        try {
            camera = Camera.open();
        } catch (Exception e) {
            camera = null;
            e.printStackTrace();
        }
        return camera;
    }

    /**
     * 打开相机并开启预览
     *
     * @param holder       SurfaceHolder
     * @param format       图片格式
     * @param width        SurfaceView宽度
     * @param height       SurfaceView高度
     * @param screenWidth  屏幕宽度
     * @param screenHeight 屏幕高度
     */
    public void openCamera(SurfaceHolder holder, int format, int width, int height, int screenWidth, int screenHeight) {
        if (this.camera != null) {
            this.camera.release();
        }
        this.camera = getCamera();
        this.setParameter(holder, format, width, height, screenWidth, screenHeight);
        this.startPreview();
    }

    /**
     * 照相
     */
    public void tackPicture(final TakePhotoCallback callback) {
        this.camera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean flag, Camera camera) {
                camera.takePicture(new Camera.ShutterCallback() {
                    @Override
                    public void onShutter() {
                        if (tone == null) {
                            //发出提示用户的声音
                            tone = new ToneGenerator(AudioManager.STREAM_MUSIC, ToneGenerator.MAX_VOLUME);
                        }
                        tone.startTone(ToneGenerator.TONE_PROP_BEEP2);
                    }
                }, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        String filepath = savePicture(data);
                        boolean success = false;
                        if (filepath != null) {
                            success = true;
                        }
                        stopPreview();
                        callback.onCapture(success, filepath);
                    }
                });
            }
        });
    }

    /**
     * 裁剪并保存照片
     *
     * @param data
     * @return
     */
    private String savePicture(byte[] data) {
        String filePath = Environment.getExternalStorageDirectory() + "/cbx/vin.jpg";
        Bitmap bitmap = cutPicture(data);
        try {
            int length = filePath.length();
            String strPath = filePath.substring(0, filePath.indexOf("v"));
            String strName = filePath.substring(filePath.indexOf("v"), length);
            if (Utils.isExist(strPath, strName)) {
                File imgFile = new File(filePath);
                FileOutputStream fos = new FileOutputStream(imgFile);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                fos.close();
                bos.flush();
                bos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }


    /**
     * 初始化相机参数
     *
     * @param holder       SurfaceHolder
     * @param format       图片格式
     * @param width        SurfaceView宽度
     * @param height       SurfaceView高度
     * @param screenWidth  屏幕宽度
     * @param screenHeight 屏幕高度
     */
    private void setParameter(SurfaceHolder holder, int format, int width, int height, int screenWidth, int screenHeight) {
        try {
            Camera.Parameters p = this.camera.getParameters();
            this.camera.setPreviewDisplay(holder);
            if (width > height) {
                //横屏
                this.camera.setDisplayOrientation(0);
            } else {
                //竖屏
                this.camera.setDisplayOrientation(90);
            }
            //照片质量
            p.set("jpeg-quality", picQuality);
            //设置照片格式
            p.setPictureFormat(ImageFormat.JPEG);
            //设置闪光灯
            p.setFlashMode(flashStatus);
            //设置最佳预览尺寸
            List previewSizes = p.getSupportedPreviewSizes();
            //设置预览分辨率
            if (this.resolution == null) {
                this.resolution = this.getOptimalPreviewSize(previewSizes, width, height);
            }
            try {
                p.setPreviewSize(this.resolution.width, this.resolution.height);
            } catch (Exception e) {
                Log.e(TAG, "不支持的预览分辨率: " + this.resolution.width + " × " + this.resolution.height);
            }
            //设置照片尺寸
            if (this.pictureSize == null) {
                List pictureSizes = p.getSupportedPictureSizes();
                this.setPicutreSize(pictureSizes, screenWidth, screenHeight);
            }
            try {
                p.setPictureSize(this.pictureSize.width, this.pictureSize.height);
            } catch (Exception e) {
                Log.e(TAG, "不支持的照片尺寸: " + this.pictureSize.width + " × " + this.pictureSize.height);
            }
            this.camera.setParameters(p);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "相机参数设置错误");
        }
    }

    /**
     * 释放Camera
     */
    public void releaseCamera() {
        if (this.camera != null) {
            if (this.isPreview) {
                this.stopPreview();
            }
            this.camera.setPreviewCallback(null);
            this.isPreview = false;
            this.camera.release();
            this.camera = null;
        }
    }

    /**
     * 停止预览
     */
    private void stopPreview() {
        if (this.camera != null && this.isPreview) {
            this.camera.stopPreview();
            this.isPreview = false;
        }
    }

    /**
     * 开始预览
     */
    public void startPreview() {
        if (this.camera != null) {
            this.camera.startPreview();
            this.camera.autoFocus(null);
            this.isPreview = true;
        }
    }

    /**
     * 裁剪照片
     *
     * @param data
     * @return
     */
    private Bitmap cutPicture(byte[] data) {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        if (this.surfaceView.getWidth() < this.surfaceView.getHeight()) {
            //竖屏旋转照片
            Matrix matrix = new Matrix();
            matrix.reset();
            matrix.setRotate(90);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }
        if (this.surfaceView == null) {
            return bitmap;
        } else {
            int[] sizes = this.surfaceView.getMaskSize();
            if (sizes[0] == 0 || sizes[1] == 0) {
                return bitmap;
            }
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();
            int x = (w - sizes[0]) / 2;
            int y = (h - sizes[1]) / 2;
            Log.i("bitmap_w--------->>>", String.valueOf(w));
            Log.i("bitmap_h--------->>>", String.valueOf(h));
            Log.i("x--------->>>", String.valueOf(x));
            Log.i("y--------->>>", String.valueOf(y));
            Log.i("w--------->>>", String.valueOf(sizes[0]));
            Log.i("h--------->>>", String.valueOf(sizes[1]));
            return Bitmap.createBitmap(bitmap, x, y, sizes[0], sizes[1]);
        }
    }

    /**
     * 获取最佳预览尺寸
     */
    private Camera.Size getOptimalPreviewSize(List sizes, int width, int height) {
        final double ASPECT_TOLERANCE = 0.05;
        double targetRatio = (double) width / height;
        if (sizes == null)
            return null;
        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        int targetHeight = height;
        // Try to find an size match aspect ratio and size
        for (Camera.Size size : sizes) {
            double r = size.width * 1.0 / size.height * 1.0;
            if (r != 4 / 3 || r != 3 / 4 || r != 16 / 9 || r != 9 / 16) {
                continue;
            }
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    /**
     * 设置照片尺寸为最接近屏幕尺寸
     *
     * @param list
     * @return
     */
    private void setPicutreSize(List list, int screenWidth, int screenHeight) {
        int approach = Integer.MAX_VALUE;
        for (Camera.Size size : list) {
            int temp = Math.abs(size.width - screenWidth + size.height - screenHeight);
            if (approach > temp) {
                approach = temp;
                this.pictureSize = size;
            }
        }
    }
}

第三步:

package com.leict.custom.maskcamera.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;

import com.leict.custom.maskcamera.camera.CameraPlateHelper;
import com.leict.custom.maskcamera.utils.Utils;

/**
 * 车牌识别
 */
public class PlateSurfaceView extends FrameLayout {
    private MSurfaceView surfaceView;
    private MaskView imageView;
    private Context mContext;
    private int width;
    private int height;
    private int maskWidth;
    private int maskHeight;
    private int screenWidth;
    private int screenHeight;

    public PlateSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        surfaceView = new MSurfaceView(context);
        imageView = new MaskView(context);
        this.addView(surfaceView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        this.addView(imageView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        this.screenHeight = Utils.getHeight(mContext);
        this.screenWidth = Utils.getWidth(mContext);
        CameraPlateHelper.getInstance(mContext).setMaskSurfaceView(this);
    }

    public void setMaskSize(Integer width, Integer height) {
        maskHeight = height;
        maskWidth = width;
    }

    public int[] getMaskSize() {
        return new MaskSize().size;
    }

    private class MSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder holder;

        @SuppressWarnings("deprecation")
        public MSurfaceView(Context context) {
            super(context);
            this.holder = this.getHolder();
            //translucent半透明 transparent透明
            this.holder.setFormat(PixelFormat.TRANSPARENT);
            this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            this.holder.addCallback(this);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            width = w;
            height = h;
            CameraPlateHelper.getInstance(mContext).openCamera(holder, format, width, height, screenWidth, screenHeight);
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            //CameraHelper.getInstance(mContext).openCamera(holder, 100, width, height, screenWidth, screenHeight);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            CameraPlateHelper.getInstance(mContext).releaseCamera();
        }
    }

    private class MaskSize {
        private int[] size;

        private MaskSize() {
            this.size = new int[]{maskWidth, maskHeight, width, height};
        }
    }

    private class MaskView extends View {
        private Paint linePaint;
        private Paint rectPaint;
        private RectF rectFLine;

        public MaskView(Context context) {
            super(context);
            //绘制中间透明区域矩形边界的Paint
            linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            linePaint.setColor(Color.WHITE);
            linePaint.setStyle(Style.STROKE);
            linePaint.setAntiAlias(true);
            linePaint.setStrokeWidth(5f);
            //绘制四周矩形阴影区域
            rectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            rectPaint.setColor(Color.BLACK);
            rectPaint.setStyle(Style.FILL);
            rectPaint.setAlpha(180);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            if (maskHeight == 0 && maskWidth == 0) {
                return;
            }
            if (maskHeight == height || maskWidth == width) {
                return;
            }
            if ((height > width && maskHeight < maskWidth) || (height < width && maskHeight > maskWidth)) {
                int temp = maskHeight;
                maskHeight = maskWidth;
                maskWidth = temp;
            }
            int h = Math.abs((height - maskHeight) / 2);
            int w = Math.abs((width - maskWidth) / 2);
            //上
            canvas.drawRect(0, 0, width, h, rectPaint);
            Log.i("上-M---------------L>>", String.valueOf(0));
            Log.i("上-M---------------T>>", String.valueOf(0));
            Log.i("上-M---------------R>>", String.valueOf(width));
            Log.i("上-M---------------B>>", String.valueOf(h));
            //右
            //canvas.drawRect(width - w, h, width, height - h, rect);
            canvas.drawRect(width - 50, h, width, width - w, rectPaint);
            Log.i("右-M---------------L>>", String.valueOf(width - w));
            Log.i("右-M---------------T>>", String.valueOf(h));
            Log.i("右-M---------------R>>", String.valueOf(width));
            Log.i("右-M---------------B>>", String.valueOf(height - h));
            //下
            //canvas.drawRect(0, height - h, width, height, this.rectPaint);
            canvas.drawRect(0, width - w, width, height, this.rectPaint);
            Log.i("下-M---------------L>>", String.valueOf(0));
            Log.i("下-M---------------T>>", String.valueOf(height - h));
            Log.i("下-M---------------R>>", String.valueOf(width));
            Log.i("下-M---------------B>>", String.valueOf(height));
            //左
            //canvas.drawRect(0, h, w, h + maskHeight, rect);
            canvas.drawRect(0, h, 50, width - w, this.rectPaint);
            Log.i("左-M---------------L>>", String.valueOf(0));
            Log.i("左-M---------------T>>", String.valueOf(h));
            Log.i("左-M---------------R>>", String.valueOf(w));
            Log.i("左-M---------------B>>", String.valueOf(h + maskHeight));
            //矩形边框的颜色
            //canvas.drawRect(w, h, w + maskWidth, h + maskHeight, linePaint);
            rectFLine = new RectF(50, h, width - 50, width - w);
            canvas.drawRoundRect(rectFLine, 10, 10, linePaint);
            Log.i("框-M---------------L>>", String.valueOf(w));
            Log.i("框-M---------------T>>", String.valueOf(h));
            Log.i("框-M---------------R>>", String.valueOf(w + maskWidth));
            Log.i("框-M---------------B>>", String.valueOf(h + maskHeight));
            super.onDraw(canvas);
        }
    }
}

第四步:

package com.leict.custom.maskcamera.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;

import com.leict.custom.maskcamera.camera.CameraVinHelper;
import com.leict.custom.maskcamera.utils.Utils;

/**
 * 车架号识别
 */
public class VinSurfaceView extends FrameLayout {
    private MSurfaceView surfaceView;
    private MaskView imageView;
    private Context mContext;
    private int width;
    private int height;
    private int maskWidth;
    private int maskHeight;
    private int screenWidth;
    private int screenHeight;

    public VinSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        surfaceView = new MSurfaceView(context);
        imageView = new MaskView(context);
        this.addView(surfaceView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        this.addView(imageView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        this.screenHeight = Utils.getHeight(mContext);
        this.screenWidth = Utils.getWidth(mContext);
        CameraVinHelper.getInstance(mContext).setMaskSurfaceView(this);
    }

    public void setMaskSize(Integer width, Integer height) {
        maskHeight = height;
        maskWidth = width;
    }

    public int[] getMaskSize() {
        return new MaskSize().size;
    }

    private class MSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder holder;

        @SuppressWarnings("deprecation")
        public MSurfaceView(Context context) {
            super(context);
            this.holder = this.getHolder();
            //translucent半透明 transparent透明
            this.holder.setFormat(PixelFormat.TRANSPARENT);
            this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            this.holder.addCallback(this);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            width = w;
            height = h;
            CameraVinHelper.getInstance(mContext).openCamera(holder, format, width, height, screenWidth, screenHeight);
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            //CameraHelper.getInstance(mContext).openCamera(holder, 100, width, height, screenWidth, screenHeight);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            CameraVinHelper.getInstance(mContext).releaseCamera();
        }
    }

    private class MaskSize {
        private int[] size;

        private MaskSize() {
            this.size = new int[]{maskWidth, maskHeight, width, height};
        }
    }

    private class MaskView extends View {
        private Paint linePaint;
        private Paint rectPaint;
        private RectF rectFLine;

        public MaskView(Context context) {
            super(context);
            //绘制中间透明区域矩形边界的Paint
            linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            linePaint.setColor(Color.WHITE);
            linePaint.setStyle(Paint.Style.STROKE);
            linePaint.setAntiAlias(true);
            linePaint.setStrokeWidth(5f);
            //绘制四周矩形阴影区域
            rectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            rectPaint.setColor(Color.BLACK);
            rectPaint.setStyle(Paint.Style.FILL);
            rectPaint.setAlpha(180);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            if (maskHeight == 0 && maskWidth == 0) {
                return;
            }
            if (maskHeight == height || maskWidth == width) {
                return;
            }
            if ((height > width && maskHeight < maskWidth) || (height < width && maskHeight > maskWidth)) {
                int temp = maskHeight;
                maskHeight = maskWidth;
                maskWidth = temp;
            }
            int h = Math.abs((height - maskHeight) / 2);
            int w = Math.abs((width - maskWidth) / 2);
            //上
            canvas.drawRect(0, 0, width, h, rectPaint);
            Log.i("上-M---------------L>>", String.valueOf(0));
            Log.i("上-M---------------T>>", String.valueOf(0));
            Log.i("上-M---------------R>>", String.valueOf(width));
            Log.i("上-M---------------B>>", String.valueOf(h));
            //右
            canvas.drawRect(width - w, h, width, height - h, rectPaint);
            Log.i("右-M---------------L>>", String.valueOf(width - w));
            Log.i("右-M---------------T>>", String.valueOf(h));
            Log.i("右-M---------------R>>", String.valueOf(width));
            Log.i("右-M---------------B>>", String.valueOf(height - h));
            //下
            canvas.drawRect(0, height - h, width, height, this.rectPaint);
            Log.i("下-M---------------L>>", String.valueOf(0));
            Log.i("下-M---------------T>>", String.valueOf(height - h));
            Log.i("下-M---------------R>>", String.valueOf(width));
            Log.i("下-M---------------B>>", String.valueOf(height));
            //左
            canvas.drawRect(0, h, w, h + maskHeight, rectPaint);
            Log.i("左-M---------------L>>", String.valueOf(0));
            Log.i("左-M---------------T>>", String.valueOf(h));
            Log.i("左-M---------------R>>", String.valueOf(w));
            Log.i("左-M---------------B>>", String.valueOf(h + maskHeight));
            //矩形边框的颜色
            rectFLine = new RectF(w, h, w + maskWidth, h + maskHeight);
            canvas.drawRoundRect(rectFLine, 10, 10, linePaint);
            Log.i("框-M---------------L>>", String.valueOf(w));
            Log.i("框-M---------------T>>", String.valueOf(h));
            Log.i("框-M---------------R>>", String.valueOf(w + maskWidth));
            Log.i("框-M---------------B>>", String.valueOf(h + maskHeight));
            super.onDraw(canvas);
        }
    }
}

 

总结:到这里大部分代码就已经写完了,剩下布局文件自己可以去布局!!!!!

你可能感兴趣的:(自定义相机,自定义相机,车牌扫描,车架号扫描)