package pr.platerecognization; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ImageFormat; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.YuvImage; import android.hardware.Camera; import android.media.Image; import android.os.Handler; import android.os.HandlerThread; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.view.Display; import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import org.greenrobot.eventbus.EventBus; import org.opencv.core.Mat; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.Policy; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * @author by hs-johnny * Created on 2019/6/17 */ public class CameraPreviews extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback { private static final String TAG = "CameraPreview"; private Camera mCamera; private SurfaceHolder mHolder; public long handle; private byte[] lock = new byte[0]; private List mResultList = new ArrayList<>(); private String currentPlate = ""; private Paint mPaint; private float oldDist = 1f; /** 停止识别*/ private boolean isStopReg; public CameraPreviews(Context context) { super(context); mHolder = getHolder(); mHolder.addCallback(this); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStrokeWidth(2); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(ContextCompat.getColor(context, R.color.colorAccent)); } public Camera getCameraInstance(){ if (mCamera == null){ try { CameraHandlerThread mThread = new CameraHandlerThread("camera thread"); synchronized (mThread){ mThread.openCamera(); } }catch (Exception e){ Log.e(TAG, "camera is not available" ); } } return mCamera; } @Override public void surfaceCreated(SurfaceHolder holder) { mCamera = getCameraInstance(); mCamera.setPreviewCallback(this); try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); setPreviewFocus(mCamera); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { int rotation = getDisplayOrientation(); mCamera.setDisplayOrientation(rotation); Camera.Parameters parameters = mCamera.getParameters(); parameters.setRotation(rotation); mCamera.setParameters(parameters); } @Override public void surfaceDestroyed(SurfaceHolder holder) { mHolder.removeCallback(this); mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } public int getDisplayOrientation(){ Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); int rotation = display.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; } Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info); int result = (info.orientation - degrees + 360) % 360; return result; } @Override public void onPreviewFrame(final byte[] data, final Camera camera) { synchronized (lock){ //处理data Camera.Size previewSize = camera.getParameters().getPreviewSize(); BitmapFactory.Options newOpts = new BitmapFactory.Options(); newOpts.inJustDecodeBounds = true; YuvImage yuvimage = new YuvImage( data, ImageFormat.NV21, previewSize.width, previewSize.height, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos); byte[] 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); PlateInfo result = MainActivity.simpleRecog(rotateBitmap(bitmap), 8); bitmap.recycle(); Log.e(TAG, "onPreviewFrame: "+result.plateName + "----time: "+ System.currentTimeMillis()); if(!isStopReg && result != null && !TextUtils.isEmpty(result.plateName)) { isStopReg = true; sendPlate(result); } } } private void sendPlate(PlateInfo plate){ EventBus.getDefault().post(plate); } private Bitmap rotateBitmap(Bitmap bmp){ Matrix matrix = new Matrix(); matrix.postRotate(90); Bitmap rotatedBitMap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); return rotatedBitMap; } private void openCameraOriginal(){ try { mCamera = Camera.open(); }catch (Exception e){ Log.e(TAG, "camera is not available"); } } private class CameraHandlerThread extends HandlerThread { Handler handler; public CameraHandlerThread(String name) { super(name); start(); handler = new Handler(getLooper()); } synchronized void notifyCameraOpened(){ notify(); } void openCamera(){ handler.post(new Runnable() { @Override public void run() { openCameraOriginal(); notifyCameraOpened(); } }); try { wait(); }catch (Exception e){ Log.e(TAG, "wait was interrupted"); } } } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getPointerCount() == 2){ switch (event.getAction()){ case MotionEvent.ACTION_POINTER_DOWN: oldDist = getFingerSpacing(event); break; case MotionEvent.ACTION_MOVE: float newDist = getFingerSpacing(event); if(newDist > oldDist){ handleZoom(true, mCamera); }else if(newDist < oldDist){ handleZoom(false, mCamera); } oldDist = newDist; break; } } return true; } private float getFingerSpacing(MotionEvent event){ float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return (float) Math.sqrt(x * x + y * y); } private void handleZoom(boolean isZoomIn, Camera camera){ Camera.Parameters parameters = camera.getParameters(); if (parameters.isZoomSupported()){ int maxZoom = parameters.getMaxZoom(); int zoom = parameters.getZoom(); if (isZoomIn && zoom < maxZoom){ zoom++; }else if(zoom > 0){ zoom--; } parameters.setZoom(zoom); camera.setParameters(parameters); }else { Log.e(TAG, "handleZoom: "+"the device is not support zoom"); } } private void setPreviewFocus(Camera camera){ Camera.Parameters parameters = camera.getParameters(); List focusList = parameters.getSupportedFocusModes(); if(focusList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); } camera.setParameters(parameters); } }