|
8 | 8 | import android.graphics.BitmapFactory;
|
9 | 9 | import android.graphics.Canvas;
|
10 | 10 | import android.graphics.Color;
|
| 11 | +import android.graphics.ImageFormat; |
| 12 | +import android.graphics.Matrix; |
11 | 13 | import android.graphics.PixelFormat;
|
12 | 14 | import android.graphics.Rect;
|
| 15 | +import android.graphics.RectF; |
13 | 16 | import android.graphics.SurfaceTexture;
|
14 | 17 | import android.hardware.camera2.CameraAccessException;
|
15 | 18 | import android.hardware.camera2.CameraCaptureSession;
|
|
18 | 21 | import android.hardware.camera2.CameraManager;
|
19 | 22 | import android.hardware.camera2.CaptureRequest;
|
20 | 23 | import android.hardware.camera2.params.StreamConfigurationMap;
|
| 24 | +import android.media.ImageReader; |
21 | 25 | import android.opengl.GLES20;
|
22 | 26 | import android.opengl.GLSurfaceView;
|
23 | 27 | import android.os.Handler;
|
24 | 28 | import android.os.HandlerThread;
|
25 | 29 | import android.util.AttributeSet;
|
26 | 30 | import android.util.Log;
|
27 | 31 | import android.util.Size;
|
| 32 | +import android.view.Surface; |
28 | 33 | import android.view.SurfaceHolder;
|
29 | 34 | import android.view.SurfaceView;
|
30 | 35 | import android.view.ViewGroup;
|
@@ -55,8 +60,11 @@ public class Camera2SurfaceView extends SurfaceView {
|
55 | 60 | private CameraManager mCameraManager;
|
56 | 61 | private CameraCaptureSession mCameraCaptureSession;
|
57 | 62 | private CameraDevice mCameraDevice;
|
| 63 | + private CameraCharacteristics characteristics; |
58 | 64 | private Handler mHandler;
|
59 | 65 |
|
| 66 | + private int orientation; |
| 67 | + |
60 | 68 | private Runnable _runnable = new SurfaceRunnable();
|
61 | 69 | private Runnable _stoppable = new SurfaceStoppable();
|
62 | 70 |
|
@@ -95,11 +103,35 @@ protected void onAttachedToWindow() {
|
95 | 103 | super.onAttachedToWindow();
|
96 | 104 | }
|
97 | 105 |
|
| 106 | + @Override |
| 107 | + protected void onDraw(Canvas canvas) { |
| 108 | + super.onDraw(canvas); |
| 109 | + canvas = getHolder().lockCanvas(); |
| 110 | +// Matrix matrix = new Matrix(); |
| 111 | +// RectF viewRect = new RectF(0, 0, screenWidth, screenHeight); |
| 112 | +// RectF bufferRect = new RectF(0, 0, previewHeight, previewWidth); |
| 113 | +// float centerX = viewRect.centerX(); |
| 114 | +// float centerY = viewRect.centerY(); |
| 115 | +// bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); |
| 116 | +// matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); |
| 117 | +// matrix.postRotate(90 * (Surface.ROTATION_90 - 2), centerX, centerY); |
| 118 | + canvas.rotate(90f); |
| 119 | + getHolder().unlockCanvasAndPost(canvas); |
| 120 | + } |
| 121 | + |
98 | 122 | public void init(Bitmap bitmap) {
|
99 | 123 | this.bitmap = bitmap;
|
100 | 124 | init();
|
101 | 125 | }
|
102 | 126 |
|
| 127 | + public void stop() { |
| 128 | + if (mCameraDevice != null) |
| 129 | + { |
| 130 | + mCameraCaptureSession.close(); |
| 131 | + mCameraDevice.close(); |
| 132 | + } |
| 133 | + } |
| 134 | + |
103 | 135 | private void init(){
|
104 | 136 | cameraThread = new HandlerThread("Camera2Thread");
|
105 | 137 | cameraThread.start();
|
@@ -188,8 +220,9 @@ private void initCamera2() {
|
188 | 220 | assert mCameraManager != null;
|
189 | 221 | String[] CameraIdList = mCameraManager.getCameraIdList();
|
190 | 222 | mCameraId = CameraIdList[0];
|
191 |
| - CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(mCameraId); |
| 223 | + characteristics = mCameraManager.getCameraCharacteristics(mCameraId); |
192 | 224 | characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
|
| 225 | + orientation = getContext().getResources().getConfiguration().orientation; |
193 | 226 | StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
194 | 227 | if(map != null){
|
195 | 228 | mSizes = map.getOutputSizes(SurfaceTexture.class);
|
@@ -232,14 +265,22 @@ public void onError(@NonNull CameraDevice cameraDevice, int i) {
|
232 | 265 | private void takePreview() {
|
233 | 266 | try {
|
234 | 267 | final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
|
235 |
| - builder.addTarget(videoRenderer.getSurface()); |
236 |
| - mCameraDevice.createCaptureSession(Collections.singletonList(videoRenderer.getSurface()), new CameraCaptureSession.StateCallback() { |
| 268 | + Surface surface = videoRenderer.getSurface(); |
| 269 | +// Surface surface = this.getHolder().getSurface(); |
| 270 | + ImageReader imageReader = ImageReader.newInstance(previewWidth, previewHeight, ImageFormat.JPEG,1); |
| 271 | + builder.addTarget(surface); |
| 272 | + ArrayList<Surface> surfaceArrayList = new ArrayList<>(); |
| 273 | + surfaceArrayList.add(surface); |
| 274 | + surfaceArrayList.add(imageReader.getSurface()); |
| 275 | + mCameraDevice.createCaptureSession(surfaceArrayList, new CameraCaptureSession.StateCallback() { |
237 | 276 | @Override
|
238 | 277 | public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
|
239 | 278 | if (null == mCameraDevice) return;
|
240 | 279 | mCameraCaptureSession = cameraCaptureSession;
|
241 | 280 | builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
|
242 | 281 | builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
|
| 282 | +// builder.set(CaptureRequest.JPEG_ORIENTATION, getJpegOrientation(characteristics, orientation)); |
| 283 | + builder.set(CaptureRequest.JPEG_ORIENTATION, Surface.ROTATION_180); |
243 | 284 | CaptureRequest previewRequest = builder.build();
|
244 | 285 | try {
|
245 | 286 | mCameraCaptureSession.setRepeatingRequest(previewRequest, null, mHandler);
|
@@ -379,6 +420,24 @@ private void drawNonAffine(float bottomLeftX, float bottomLeftY, float bottomRig
|
379 | 420 | }
|
380 | 421 | }
|
381 | 422 |
|
| 423 | + private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) { |
| 424 | + if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN) return 0; |
| 425 | + int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION); |
| 426 | + |
| 427 | + // Round device orientation to a multiple of 90 |
| 428 | + deviceOrientation = (deviceOrientation + 45) / 90 * 90; |
| 429 | + |
| 430 | + // Reverse device orientation for front-facing cameras |
| 431 | + boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT; |
| 432 | + if (facingFront) deviceOrientation = -deviceOrientation; |
| 433 | + |
| 434 | + // Calculate desired JPEG orientation relative to camera orientation to make |
| 435 | + // the image upright relative to the device orientation |
| 436 | + int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360; |
| 437 | + |
| 438 | + return jpegOrientation; |
| 439 | + } |
| 440 | + |
382 | 441 | private class SurfaceRunnable implements Runnable {
|
383 | 442 | @Override
|
384 | 443 | public void run() {
|
|
0 commit comments