| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- package com.miekir.ocr;
- import android.Manifest;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.content.res.Configuration;
- import android.graphics.ImageFormat;
- import android.graphics.Point;
- import android.graphics.SurfaceTexture;
- import android.hardware.camera2.CameraAccessException;
- import android.hardware.camera2.CameraCaptureSession;
- import android.hardware.camera2.CameraCharacteristics;
- import android.hardware.camera2.CameraDevice;
- import android.hardware.camera2.CameraManager;
- import android.hardware.camera2.CameraMetadata;
- import android.hardware.camera2.CaptureRequest;
- import android.hardware.camera2.TotalCaptureResult;
- import android.hardware.camera2.params.StreamConfigurationMap;
- import android.media.Image;
- import android.media.ImageReader;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.util.Log;
- import android.util.Size;
- import android.util.SparseIntArray;
- import android.view.Surface;
- import android.view.TextureView;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
- import androidx.annotation.NonNull;
- import com.miekir.ocr.base.BaseCameraActivity;
- import com.miekir.ocr.tool.Utils;
- import com.miekir.ocr.view.AutoFitTextureView;
- import com.tbruyelle.rxpermissions2.RxPermissions;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.ByteBuffer;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.TimeUnit;
- import static android.os.Environment.DIRECTORY_PICTURES;
- public class CameraActivity extends BaseCameraActivity {
- private static SparseIntArray ORIENTATIONS = new SparseIntArray();
- static {
- ORIENTATIONS.append(Surface.ROTATION_0, 90);
- ORIENTATIONS.append(Surface.ROTATION_90, 0);
- ORIENTATIONS.append(Surface.ROTATION_180, 270);
- ORIENTATIONS.append(Surface.ROTATION_270, 180);
- }
- private String cameraId;
- private CameraDevice cameraDevice;
- private CameraCaptureSession cameraCaptureSessions;
- private CaptureRequest.Builder captureRequestBuilder;
- private Size imageDimension;
- private ImageReader imageReader;
- private File file = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/" + System.currentTimeMillis() + ".jpg");
- private static final int REQUEST_CAMERA_PERMISSION = 200;
- private Handler mBackgroundHandler;
- private HandlerThread mBackgroundThread;
- private AutoFitTextureView textureView;
- private Button button;
- private Semaphore mCameraOpenCloseLock = new Semaphore(1);
- private static final int MAX_PREVIEW_WIDTH = 1920;
- private static final int MAX_PREVIEW_HEIGHT = 1080;
- private int mSensorOrientation;
- private TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- openCamera(width, height);
- }
- @Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- if (null != textureView || null == imageDimension) {
- textureView.setTransform(Utils.configureTransform(width, height, imageDimension, CameraActivity.this));
- }
- }
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- return false;
- }
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- }
- };
- private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
- @Override
- public void onOpened(CameraDevice camera) {
- Log.e("tag", "onOpened");
- mCameraOpenCloseLock.release();
- cameraDevice = camera;
- createCameraPreview();
- }
- @Override
- public void onDisconnected(CameraDevice camera) {
- mCameraOpenCloseLock.release();
- cameraDevice.close();
- }
- @Override
- public void onError(CameraDevice camera, int error) {
- mCameraOpenCloseLock.release();
- cameraDevice.close();
- cameraDevice = null;
- }
- };
- @Override
- public int getLayoutID() {
- return R.layout.activity_camera;
- }
- @SuppressLint("CheckResult")
- @Override
- public void initViews(Bundle savedInstanceState) {
- textureView = (AutoFitTextureView) findViewById(R.id.textureView);
- button = (Button) findViewById(R.id.button);
- textureView.setSurfaceTextureListener(textureListener);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- takePicture();
- }
- });
- }
- private void openCamera(int width, int height) {
- CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
- Log.e("tag", "is camera open");
- try {
- if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
- throw new RuntimeException("Time out waiting to lock camera opening.");
- }
- cameraId = manager.getCameraIdList()[0];
- CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
- StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
- assert map != null;
- Size largest = Collections.max(
- Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
- new Utils.CompareSizesByArea());
- int displayRotation = getWindowManager().getDefaultDisplay().getRotation();
- //noinspection ConstantConditions
- mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
- boolean swappedDimensions = false;
- switch (displayRotation) {
- case Surface.ROTATION_0:
- case Surface.ROTATION_180:
- if (mSensorOrientation == 90 || mSensorOrientation == 270) {
- swappedDimensions = true;
- }
- break;
- case Surface.ROTATION_90:
- case Surface.ROTATION_270:
- if (mSensorOrientation == 0 || mSensorOrientation == 180) {
- swappedDimensions = true;
- }
- break;
- default:
- Log.e("tag", "Display rotation is invalid: " + displayRotation);
- }
- Point displaySize = new Point();
- getWindowManager().getDefaultDisplay().getSize(displaySize);
- int rotatedPreviewWidth = width;
- int rotatedPreviewHeight = height;
- int maxPreviewWidth = displaySize.x;
- int maxPreviewHeight = displaySize.y;
- if (swappedDimensions) {
- rotatedPreviewWidth = height;
- rotatedPreviewHeight = width;
- maxPreviewWidth = displaySize.y;
- maxPreviewHeight = displaySize.x;
- }
- if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
- maxPreviewWidth = MAX_PREVIEW_WIDTH;
- }
- if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
- maxPreviewHeight = MAX_PREVIEW_HEIGHT;
- }
- imageDimension = Utils.chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
- rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
- maxPreviewHeight, largest);
- int orientation = getResources().getConfiguration().orientation;
- if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
- textureView.setAspectRatio(
- imageDimension.getWidth(), imageDimension.getHeight());
- } else {
- textureView.setAspectRatio(
- imageDimension.getHeight(), imageDimension.getWidth());
- }
- if (null != textureView || null == imageDimension) {
- textureView.setTransform(Utils.configureTransform(width, height, imageDimension, CameraActivity.this));
- }
- manager.openCamera(cameraId, stateCallback, null);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- Log.e("tag", "openCamera X");
- }
- protected void createCameraPreview() {
- try {
- SurfaceTexture texture = textureView.getSurfaceTexture();
- assert texture != null;
- texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
- Surface surface = new Surface(texture);
- captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
- captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
- captureRequestBuilder.addTarget(surface);
- cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
- @Override
- public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
- //The camera is already closed
- if (null == cameraDevice) {
- return;
- }
- // When the session is ready, we start displaying the preview.
- cameraCaptureSessions = cameraCaptureSession;
- updatePreview();
- }
- @Override
- public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
- Toast.makeText(CameraActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
- }
- }, null);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- }
- }
- protected void updatePreview() {
- if (null == cameraDevice) {
- Log.e("tag", "updatePreview error, return");
- }
- captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
- try {
- cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- }
- }
- protected void startBackgroundThread() {
- mBackgroundThread = new HandlerThread("Camera Background");
- mBackgroundThread.start();
- mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
- }
- protected void stopBackgroundThread() {
- mBackgroundThread.quitSafely();
- try {
- mBackgroundThread.join();
- mBackgroundThread = null;
- mBackgroundHandler = null;
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- private void closeCamera() {
- try {
- mCameraOpenCloseLock.acquire();
- if (null != cameraCaptureSessions) {
- cameraCaptureSessions.close();
- cameraCaptureSessions = null;
- }
- if (null != cameraDevice) {
- cameraDevice.close();
- cameraDevice = null;
- }
- if (null != imageReader) {
- imageReader.close();
- imageReader = null;
- }
- } catch (InterruptedException e) {
- throw new RuntimeException("Interrupted while trying to lock camera closing.");
- } finally {
- mCameraOpenCloseLock.release();
- }
- }
- @Override
- protected void onResume() {
- super.onResume();
- Log.e("tag", "onResume");
- startBackgroundThread();
- if (textureView.isAvailable()) {
- openCamera(textureView.getWidth(), textureView.getHeight());
- } else {
- textureView.setSurfaceTextureListener(textureListener);
- }
- }
- @Override
- protected void onPause() {
- Log.e("tag", "onPause");
- closeCamera();
- stopBackgroundThread();
- super.onPause();
- }
- protected void takePicture() {
- if (null == cameraDevice) {
- Log.e("tag", "cameraDevice is null");
- return;
- }
- CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
- try {
- CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
- Size[] jpegSizes = null;
- if (characteristics != null) {
- jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
- }
- int width = 640;
- int height = 480;
- if (jpegSizes != null && 0 < jpegSizes.length) {
- width = jpegSizes[0].getWidth();
- height = jpegSizes[0].getHeight();
- }
- ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
- List<Surface> outputSurfaces = new ArrayList<Surface>(2);
- outputSurfaces.add(reader.getSurface());
- outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
- final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
- captureBuilder.addTarget(reader.getSurface());
- captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
- // Orientation
- int rotation = getWindowManager().getDefaultDisplay().getRotation();
- captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
- reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
- final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
- @Override
- public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
- super.onCaptureCompleted(session, request, result);
- Toast.makeText(CameraActivity.this, "Saved:" + file, Toast.LENGTH_SHORT).show();
- createCameraPreview();
- }
- };
- cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
- @Override
- public void onConfigured(CameraCaptureSession session) {
- try {
- session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void onConfigureFailed(CameraCaptureSession session) {
- }
- }, mBackgroundHandler);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- }
- }
- ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
- @Override
- public void onImageAvailable(ImageReader reader) {
- Image image = null;
- try {
- image = reader.acquireLatestImage();
- ByteBuffer buffer = image.getPlanes()[0].getBuffer();
- byte[] bytes = new byte[buffer.capacity()];
- buffer.get(bytes);
- save(bytes);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (image != null) {
- image.close();
- }
- }
- }
- private void save(byte[] bytes) throws IOException {
- OutputStream output = null;
- try {
- output = new FileOutputStream(file);
- output.write(bytes);
- } finally {
- if (null != output) {
- output.close();
- }
- }
- }
- };
- }
|