package com.zhaoss.weixinrecorded.util; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; 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.CaptureRequest; import android.hardware.camera2.params.StreamConfigurationMap; import android.media.Image; import android.media.ImageReader; import android.os.Handler; import android.os.HandlerThread; import android.support.annotation.NonNull; import android.util.Size; import android.view.Surface; import android.widget.ImageView; import com.lansosdk.videoeditor.LanSongFileUtil; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; /** * Created by zhaoshuang on 2018/7/20. */ public class CameraHelp2 { private Context mContext; private int defaultSize = 1920 * 1080; private CameraManager cameraManager; private CameraDevice mCameraDevice; private CaptureRequest.Builder previewRequestBuilder; private SurfaceTexture surfaceTexture; private Handler mHandler; private int[] previewSize; private CameraCaptureSession mCameraCaptureSession; private ImageReader mImageReader; private int mOrientation; public CameraHelp2(Context context){ this.mContext = context; HandlerThread handlerThread = new HandlerThread("CameraHelp2"); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); } @SuppressLint("MissingPermission") public void openCamera(SurfaceTexture surfaceTexture, final ImageView imageView) { try { this.surfaceTexture = surfaceTexture; String[] ids = cameraManager.getCameraIdList(); String cameraId = ""; for (String id : ids) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); Integer cameraOrientation = characteristics.get(CameraCharacteristics.LENS_FACING); Integer sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); if(cameraOrientation == CameraCharacteristics.LENS_FACING_BACK){ cameraId = id; mOrientation = sensorOrientation; } } CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); previewSize = getPreviewSize(map); mImageReader = ImageReader.newInstance(previewSize[0], previewSize[1], ImageFormat.JPEG, 1); mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { Image image = reader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] imgs = new byte[buffer.remaining()]; buffer.get(imgs); try { Bitmap bitmap = BitmapFactory.decodeByteArray(imgs, 0, imgs.length); Matrix matrix = new Matrix(); matrix.setRotate(mOrientation); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); String photoPath = LanSongFileUtil.DEFAULT_DIR+System.currentTimeMillis()+".jpeg"; FileOutputStream fos = new FileOutputStream(photoPath); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.close(); }catch (IOException e){ e.printStackTrace(); } image.close(); } }, mHandler); cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { mCameraDevice = camera; createCameraSession(); } @Override public void onDisconnected(@NonNull CameraDevice camera) { camera.close(); mCameraDevice = null; } @Override public void onError(@NonNull CameraDevice camera, int error) { camera.close(); mCameraDevice = null; } }, mHandler); } catch (Exception e) { e.printStackTrace(); } } public void shotPhoto(){ try { CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureRequestBuilder.addTarget(mImageReader.getSurface()); // 自动对焦 captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // 自动曝光 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mOrientation); CaptureRequest captureRequest = captureRequestBuilder.build(); mCameraCaptureSession.capture(captureRequest, null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } public void openFlash(){ try { previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); CaptureRequest previewRequest = previewRequestBuilder.build(); mCameraCaptureSession.setRepeatingRequest(previewRequest, null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } public void closeFlash(){ try { previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); CaptureRequest previewRequest = previewRequestBuilder.build(); mCameraCaptureSession.setRepeatingRequest(previewRequest, null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private void createCameraSession() { try { previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); Surface previewSurface = new Surface(surfaceTexture); previewRequestBuilder.addTarget(previewSurface); mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { try { mCameraCaptureSession = cameraCaptureSession; previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); CaptureRequest previewRequest = previewRequestBuilder.build(); cameraCaptureSession.setRepeatingRequest(previewRequest, null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { } }, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } //摄像大小 private int[] getPreviewSize(StreamConfigurationMap map){ Size[] sizes = map.getOutputSizes(ImageFormat.JPEG); int[] previewSize = new int[2]; boolean flag = false; for (Size size : sizes) { if (size.getWidth() * size.getHeight() == defaultSize) { previewSize[0] = size.getWidth(); previewSize[1] = size.getHeight(); flag = true; } } if (!flag) { int difference = 0; int position = 0; for (int x=0; x<sizes.length; x++) { Size size = sizes[x]; int n = Math.abs(defaultSize - size.getWidth() * size.getHeight()); if (x == 0 || difference > n) { difference = n; position = x; } } previewSize[0] = sizes[position].getWidth(); previewSize[1] = sizes[position].getHeight(); } return previewSize; } private byte[] getYUVI420(Image image){ int width = image.getWidth(); int height = image.getHeight(); byte[] yuvI420 = new byte[image.getWidth()*image.getHeight()*3/2]; byte[] yData = new byte[image.getPlanes()[0].getBuffer().remaining()]; byte[] uData = new byte[image.getPlanes()[1].getBuffer().remaining()]; byte[] vData = new byte[image.getPlanes()[2].getBuffer().remaining()]; image.getPlanes()[0].getBuffer().get(yData); image.getPlanes()[1].getBuffer().get(uData); image.getPlanes()[2].getBuffer().get(vData); System.arraycopy(yData, 0, yuvI420, 0, yData.length); int index = yData.length; for (int r = 0; r < height / 2; ++r) { for (int c = 0; c < width; c += 2) { //各一个byte存一个U值和V值 yuvI420[index++] = uData[r * width + c]; } } for (int r = 0; r < height / 2; ++r) { for (int c = 0; c < width; c += 2) { //各一个byte存一个U值和V值 yuvI420[index++] = vData[r * width + c]; } } return yuvI420; } }