Files
HyperLPR-Windows-Shared/Prj-Android/app/src/main/java/pr/platerecognization/CameraPreviews.java
T

270 lines
8.8 KiB
Java
Executable File

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<String> 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<String> focusList = parameters.getSupportedFocusModes();
if(focusList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
camera.setParameters(parameters);
}
}