package com.basic.security.widget;
|
|
import android.content.Context;
|
import android.content.ContextWrapper;
|
import android.content.res.Configuration;
|
import android.graphics.Bitmap;
|
import android.hardware.Camera;
|
import android.hardware.SensorManager;
|
import android.util.AttributeSet;
|
import android.view.OrientationEventListener;
|
import android.view.SurfaceHolder;
|
import android.view.ViewGroup;
|
|
import com.basic.security.base.BaseApplication;
|
import com.basic.security.utils.BgrUtils;
|
import com.basic.security.utils.Constants;
|
import com.basic.security.utils.DetectListener;
|
import com.basic.security.utils.FaceId;
|
import com.basic.security.utils.ProcessImageAndDrawResults;
|
import com.basic.security.utils.RenderScriptHelper;
|
import com.basic.security.utils.RotateUtil;
|
import com.basic.security.utils.socket.RelaySocketServer;
|
import com.basic.security.utils.socket.outdoor.OutdoorGuestSocketServer;
|
|
import java.io.ByteArrayOutputStream;
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.util.List;
|
|
public class Preview extends PreviewBase {
|
Preview.MyThread rgbThread = new Preview.MyThread();
|
Preview.MyThread grayThread = new Preview.MyThread();
|
|
public Preview(Context context, AttributeSet attrs) {
|
super(context, attrs);
|
}
|
|
public void setMeasuredDimension1(int measuredWidth, int measuredHeight) {
|
setMeasuredDimension(measuredWidth, measuredHeight);
|
}
|
|
@Override
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
// ViewAttributeManager.onMeasure(this, widthMeasureSpec, heightMeasureSpec);
|
}
|
|
@Override
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
super.onLayout(changed, left, top, right, bottom);
|
}
|
|
public void reset() {
|
if (mCamera != null) {
|
try {
|
mCamera.release();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
surfaceCreated(mHolder);
|
surfaceChanged(mHolder, 0, 0, 0);
|
}
|
|
public void surfaceCreated(final SurfaceHolder holder) {
|
// System1.out.println("Preview.surfaceCreated rgb_gray_camera="+rgb_gray_camera);
|
// if (1 == 1) {
|
// return;
|
// }
|
mFinished = false;
|
try {
|
mCamera = Camera.open(rgb_gray_camera);
|
Camera.Parameters parameters = mCamera.getParameters();
|
parameters.setPreviewSize(640, 480);
|
mCamera.setParameters(parameters);
|
mCamera.setPreviewDisplay(holder);
|
resetCamera = true;
|
mCamera.setPreviewCallback((data, camera) -> {
|
lastTimeOnPreviewFrame = System.currentTimeMillis();
|
if (Constants.indoorOutdoorInOne) {
|
if (rgb_gray_camera == Constants.RGB_CAMERA) {
|
if (secondDisplayRunnable.isNotRunning()) {
|
if (data == null) {
|
return;
|
}
|
secondDisplayRunnable.isRunning = true;
|
secondDisplayRunnable.setFrame(data, mDraw);
|
BaseApplication.getApplication().executorService.execute(secondDisplayRunnable);
|
}
|
}
|
}
|
try {
|
if (rgb_gray_camera == Constants.RGB_CAMERA) {
|
OutdoorGuestSocketServer.setCameraData(data);
|
if (BaseApplication.getApplication().activity != null
|
&& BaseApplication.getApplication().activity.shouldDetectFace()) {
|
if (!rgbThread.isRunning) {
|
if (Constants.USE_GRAY_CAMERA) {
|
byte[] grayBgrData = getMostMatchGrayBgrData();
|
if (grayBgrData != null) {
|
try {
|
System1.out.println("Preview.surfaceCreated grayThread");
|
grayThread.onPreviewFrame(grayBgrData, camera, Constants.GRAY_CAMERA);
|
grayExecutorService.execute(grayThread);
|
} catch (Exception e) {
|
grayThread.isRunning = false;
|
e.printStackTrace();
|
}
|
}
|
}
|
rgbThread.isRunning = true;
|
rgbThread.onPreviewFrame(data, camera, Constants.RGB_CAMERA);
|
rgbExecutorService.execute(rgbThread);
|
}
|
}
|
} else {
|
updateGrayBgrData(data);
|
}
|
} catch (Exception e) {
|
rgbThread.isRunning = false;
|
e.printStackTrace();
|
}
|
});
|
mCamera.startPreview();
|
OrientationEventListener mOrientationListener = new OrientationEventListener(FaceId.activity,
|
SensorManager.SENSOR_DELAY_NORMAL) {
|
public void onOrientationChanged(int orientation) {
|
if (orientation == ORIENTATION_UNKNOWN) return;
|
Camera.CameraInfo info = new Camera.CameraInfo();
|
Camera.getCameraInfo(0, info);
|
orientation = (orientation + 45) / 90 * 90;
|
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
Preview.rotation = (info.orientation - orientation + 360) % 360;
|
} else {
|
Preview.rotation = (info.orientation + orientation) % 360;
|
}
|
orientation1 = orientation;
|
}
|
};
|
if (mOrientationListener.canDetectOrientation()) {
|
mOrientationListener.enable();
|
} else {
|
mOrientationListener.disable();
|
}
|
} catch (Exception exception) {
|
System1.out.println("Preview.surfaceCreated " + exception.getMessage());
|
if (mCamera != null) {
|
mCamera.release();
|
mCamera = null;
|
}
|
mFinished = true;
|
}
|
}
|
|
public void updateGrayBgrData(byte[] data) {
|
// System1.out.println("Preview.updateGrayBgrData " + data);
|
grayCameraData = data;
|
grayCameraDataLastTimeUpdate = System.currentTimeMillis();
|
}
|
|
public byte[] getMostMatchGrayBgrData() {
|
long internal = (System.currentTimeMillis() - grayCameraDataLastTimeUpdate);
|
if (internal < 1000 && grayCameraData != null) {
|
return grayCameraData;
|
}
|
return null;
|
}
|
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
// if (1 == 1) {
|
// return;
|
// }
|
mFinished = true;
|
if (mCamera != null) {
|
mCamera.setPreviewCallback(null);
|
mCamera.stopPreview();
|
mCamera.release();
|
mCamera = null;
|
}
|
}
|
|
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
if (mFinished) {
|
return;
|
}
|
// if (1 == 1) {
|
// return;
|
// }
|
if (mCamera == null) return;
|
Camera.Parameters parameters = mCamera.getParameters();
|
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
|
parameters.set("orientation", "portrait");
|
mCamera.setDisplayOrientation(90);
|
mDraw.rotated = true;
|
} else {
|
parameters.set("orientation", "landscape");
|
mCamera.setDisplayOrientation(0);
|
}
|
List<Camera.Size> supportedSizes = parameters.getSupportedPreviewSizes();
|
int width = 0;
|
int height = 0;
|
for (Camera.Size s : supportedSizes) {
|
if ((width - 640) * (width - 640) + (height - 480) * (height - 480) >
|
(s.width - 640) * (s.width - 640) + (s.height - 480) * (s.height - 480)) {
|
width = s.width;
|
height = s.height;
|
}
|
}
|
try {
|
if (width * height > 0) {
|
parameters.setPreviewSize(width, height);
|
}
|
parameters.setSceneMode(Camera.Parameters.SCENE_MODE_LANDSCAPE);
|
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
|
mCamera.setParameters(parameters);
|
} catch (Exception ex) {
|
// System1.out.println("Preview.surfaceChanged " + ex.getMessage());
|
}
|
parameters = mCamera.getParameters();
|
Camera.Size previewSize = parameters.getPreviewSize();
|
makeResizeForCameraAspect(1.0f / ((1.0f * previewSize.width) / previewSize.height));
|
}
|
|
private void makeResizeForCameraAspect(float cameraAspectRatio) {
|
ViewGroup.LayoutParams layoutParams = this.getLayoutParams();
|
int matchParentWidth = this.getWidth();
|
int newHeight = (int) (matchParentWidth / cameraAspectRatio);
|
if (newHeight != layoutParams.height) {
|
layoutParams.height = newHeight;
|
layoutParams.width = matchParentWidth;
|
this.setLayoutParams(layoutParams);
|
this.invalidate();
|
}
|
}
|
|
public void init(Context context, int rgb_gray_camera, DetectListener detectListener) {
|
if (rgb_gray_camera == Constants.RGB_CAMERA && Constants.indoorOutdoorInOne) {
|
init1(context, rgb_gray_camera, detectListener);
|
return;
|
}
|
// System1.out.println("Preview.init " + rgb_gray_camera);
|
if (rgb_gray_camera == Constants.RGB_CAMERA) {
|
Preview.rgbPreview = this;
|
RelaySocketServer.startSocketServer();
|
}
|
if (rgb_gray_camera == Constants.GRAY_CAMERA) {
|
Preview.grayPreview = this;
|
}
|
this.detectListener = detectListener;
|
mContext = context;
|
mDraw = new ProcessImageAndDrawResults(rgb_gray_camera);
|
this.rgb_gray_camera = rgb_gray_camera;
|
mHolder = getHolder();
|
mHolder.addCallback(this);
|
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
}
|
|
public void init1(Context context, int rgb_gray_camera, DetectListener detectListener) {
|
if (rgb_gray_camera == Constants.RGB_CAMERA) {
|
Preview.rgbPreview = this;
|
RelaySocketServer.startSocketServer();
|
}
|
if (rgb_gray_camera == Constants.GRAY_CAMERA) {
|
Preview.grayPreview = this;
|
}
|
this.detectListener = detectListener;
|
mContext = context;
|
mDraw = new ProcessImageAndDrawResults(rgb_gray_camera);
|
this.rgb_gray_camera = rgb_gray_camera;
|
mHolder = getHolder();
|
mHolder.addCallback(this);
|
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
}
|
|
public static class SecondDisplayRunnable implements Runnable {
|
public boolean isRunning = false;
|
public long lastRunningTime = System.currentTimeMillis();
|
public byte[] data;
|
public ProcessImageAndDrawResults mDraw;
|
RenderScriptHelper renderScriptHelper = new RenderScriptHelper();
|
|
public void setFrame(byte[] data, ProcessImageAndDrawResults mDraw) {
|
if (this.data == null || this.data.length != data.length) {
|
this.data = new byte[data.length];
|
}
|
System.arraycopy(data, 0, this.data, 0, data.length);
|
this.mDraw = mDraw;
|
}
|
|
///** Convert I420 (YYYYYYYY:UU:VV) to NV21 (YYYYYYYYY:VUVU) */
|
@Override
|
public void run() {
|
secondDisplayRunnable.lastRunningTime = System.currentTimeMillis();
|
if (data != null && mDraw != null) {
|
try {
|
if (Constants.indoorOutdoorInOne) {
|
// RotateUtil.mirror(data, mDraw.mImageWidth, mDraw.mImageHeight);
|
}
|
// System1.out.println("SecondDisplayRunnable.run 0 ");
|
// int yuvStrides[] = {mDraw.mImageWidth, mDraw.mImageWidth/2, mDraw.mImageWidth/2};
|
// VideoRenderer.I420Frame i420Frame = new VideoRenderer.I420Frame(mDraw.mImageWidth, mDraw.mImageHeight, yuvStrides,
|
// RotateUtil.nv21ToI420(data, mDraw.mImageWidth, mDraw.mImageHeight));
|
// if ( BaseApplication.getApplication().activity.secondaryDisplay != null) {
|
//// System1.out.println("SecondDisplayRunnable.run 1 " + BaseApplication.getApplication().activity.secondaryDisplay);
|
// if(BaseApplication.getApplication().activity.secondaryDisplay.yuvImageRenderer != null) {
|
//// System1.out.println("SecondDisplayRunnable.run 2 " + BaseApplication.getApplication().activity.secondaryDisplay.yuvImageRenderer);
|
// BaseApplication.getApplication().activity.secondaryDisplay.yuvImageRenderer.setSize(mDraw.mImageWidth, mDraw.mImageHeight);
|
// BaseApplication.getApplication().activity.secondaryDisplay.yuvImageRenderer.renderFrame(i420Frame);
|
// }
|
// }
|
Bitmap frameBitmap = null;
|
frameBitmap = renderScriptHelper.getBitmapFromFrameData(data, mDraw.mImageWidth, mDraw.mImageHeight);
|
//// Matrix mtx = new Matrix();
|
//// mtx.preScale(-1.0f, 1.0f);
|
//// Bitmap newImage = Bitmap.createBitmap(frameBitmap, 0, 0, frameBitmap.getWidth(), frameBitmap.getHeight(), mtx, true);
|
BaseApplication.getApplication().activity.updateCameraImagesInSecondDisplay(frameBitmap);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
public boolean isNotRunning() {
|
if (System.currentTimeMillis() - lastRunningTime < 1000.0 / 18) {
|
return false;
|
}
|
return System.currentTimeMillis() - lastRunningTime > 1 * 1000 || !isRunning;
|
}
|
}
|
|
class MyThread implements Runnable {
|
public boolean isRunning = false;
|
RotateUtil rotateUtil = new RotateUtil();
|
BgrUtils bgrUtils = new BgrUtils();
|
ByteArrayOutputStream jpgBaos = new ByteArrayOutputStream();
|
byte[] data;
|
Camera camera;
|
int rgb_gray_camera;
|
RenderScriptHelper renderScriptHelper = new RenderScriptHelper();
|
Camera.Parameters params;
|
|
public void onPreviewFrame(byte[] data, Camera camera, int rgb_gray_camera) {
|
this.rgb_gray_camera = rgb_gray_camera;
|
if (this.data == null) {
|
this.data = new byte[data.length];
|
}
|
if (BaseApplication.getApplication().activity.needCopyCameraData()) {
|
System.arraycopy(data, 0, this.data, 0, data.length);
|
} else {
|
this.data = data;
|
}
|
this.data = data;
|
this.camera = camera;
|
}
|
|
public void run() {
|
ProcessImageAndDrawResults mDraw;
|
if (rgb_gray_camera == Constants.GRAY_CAMERA) {
|
mDraw = grayPreview.mDraw;
|
} else {
|
mDraw = rgbPreview.mDraw;
|
}
|
mDraw.originalCameraData = this.data;
|
isRunning = true;
|
mDraw.setRgb_gray_camera(rgb_gray_camera);
|
if (params == null) {
|
params = camera.getParameters();
|
}
|
int rotation = Constants.rotation;
|
if (rotation == 360 || rotation == 0) {
|
mDraw.mImageWidth = params.getPreviewSize().width;
|
mDraw.mImageHeight = params.getPreviewSize().height;
|
}
|
if (rotation == 270) {
|
data = rotateUtil.rotateYUV420Degree270(data, params.getPreviewSize().width, params.getPreviewSize().height);
|
mDraw.mImageWidth = params.getPreviewSize().height;
|
mDraw.mImageHeight = params.getPreviewSize().width;
|
}
|
if (rotation == 180) {
|
data = rotateUtil.rotateYUV420Degree180(data, params.getPreviewSize().width, params.getPreviewSize().height);
|
mDraw.mImageWidth = params.getPreviewSize().width;
|
mDraw.mImageHeight = params.getPreviewSize().height;
|
}
|
if (rotation == 90) {
|
data = rotateUtil.rotateYUV420Degree90(data, params.getPreviewSize().width, params.getPreviewSize().height);
|
mDraw.mImageWidth = params.getPreviewSize().height;
|
mDraw.mImageHeight = params.getPreviewSize().width;
|
}
|
Preview.this.rotationToSend = rotation;
|
if (!Constants.useNv21ToBgr) {
|
long begin = System.currentTimeMillis();
|
// byte[] dataBGR = new byte[640*480*3];
|
// dataBGR = FaceId.instance.yuv420p2rgb24(data, dataBGR,480, 640);
|
// System1.out.println("MyThread.run " + (System.currentTimeMillis() - begin));
|
// YuvImage im = new YuvImage(data, ImageFormat.NV21, mDraw.mImageWidth,
|
// mDraw.mImageHeight, null);
|
// Rect r = new Rect(0, 0, mDraw.mImageWidth, mDraw.mImageHeight);
|
// jpgBaos.reset();
|
// im.compressToJpeg(r, params.getJpegQuality(), jpgBaos);
|
String outputFileName = "";
|
Bitmap frameBitmap = renderScriptHelper.getBitmapFromFrameData(data, mDraw.mImageWidth, mDraw.mImageHeight);// Bitmap.createBitmap(640, 480, Bitmap.Config.RGB_565);
|
byte[] bgrArray = null;
|
try {
|
String name = "";
|
String filesPath = new ContextWrapper(FaceId.activity).getFilesDir().getAbsolutePath();
|
byte[] jpgByteArray = null;
|
if (rgb_gray_camera == Constants.RGB_CAMERA) {
|
name = "image_rgb.jpg";
|
outputFileName = "rgb.jpg";
|
File targetFile = new File(filesPath, outputFileName);
|
// jpgByteArray = jpgBaos.toByteArray();
|
// frameBitmap = BitmapFactory.decodeByteArray(jpgByteArray, 0, jpgBaos.size());
|
jpgBaos.reset();
|
frameBitmap.compress(Bitmap.CompressFormat.JPEG, 100, jpgBaos);
|
mDraw.frameJpgByteArray = jpgBaos.toByteArray();
|
jpgByteArray = mDraw.frameJpgByteArray;
|
mDraw.frameBitmap = frameBitmap;
|
bgrArray = bgrUtils.getPixelsBGR(frameBitmap);
|
if (!Constants.useBgrArray) {
|
FileOutputStream outputStream = new FileOutputStream(targetFile);
|
outputStream.write(bgrArray);
|
outputStream.close();
|
}
|
} else {
|
outputFileName = "gray.jpg";
|
name = "image_gray.jpg";
|
jpgBaos.reset();
|
frameBitmap.compress(Bitmap.CompressFormat.JPEG, 100, jpgBaos);
|
mDraw.frameJpgByteArray = jpgBaos.toByteArray();
|
jpgByteArray = mDraw.frameJpgByteArray;
|
mDraw.frameBitmap = frameBitmap;
|
bgrArray = bgrUtils.getPixelsBGR(frameBitmap);
|
// Bitmap bitmap = BitmapFactory.decodeByteArray(jpgBaos.toByteArray(), 0, jpgBaos.size());
|
// bitmapHolder.storeBitmap(bitmap);
|
// bitmapHolder.flipBitmapHorizontal();
|
// bitmap = bitmapHolder.getBitmapAndFree();
|
// jpgBaos.reset();
|
// if (bitmap == null) {
|
// System1.out.println("MyThread.run bitmap=" + bitmap);
|
// isRunning = false;
|
// return;
|
// }
|
// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, jpgBaos);
|
// jpgByteArray = jpgBaos.toByteArray();
|
File targetFile = new File(filesPath, outputFileName);
|
FileOutputStream outputStream = new FileOutputStream(targetFile);
|
// bgrArray = bgrUtils.getPixelsBGR(BitmapFactory.decodeByteArray(jpgByteArray, 0, jpgBaos.size()));
|
outputStream.write(bgrArray);
|
outputStream.close();
|
}
|
FileOutputStream output = new FileOutputStream(new File(new ContextWrapper(getContext()).getFilesDir().getAbsolutePath(), name));
|
output.write(jpgByteArray);
|
output.flush();
|
output.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
if (mFinished)
|
return;
|
if (mDraw.mYUVData == null) {
|
mDraw.mRGBData = new byte[3 * mDraw.mImageWidth * mDraw.mImageHeight];
|
mDraw.mYUVData = new byte[data.length];
|
}
|
mDraw.start(frameBitmap, bgrArray, data);
|
} else {
|
mDraw.start1(data);
|
}
|
isRunning = false;
|
}
|
}
|
}
|