package com.example.xinlai_001.camerademo;
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
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.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.print.PrinterId;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ToggleButton;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* 使用surfaceview camera2 实现相机预览
*/
public class Camera2Activity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
CameraManager cameraManager;
CameraDevice cameraDevice;
CameraCaptureSession cameraCaptureSession;
ImageReader imageReader;
Handler childHandler;
Handler mainHandler;
String cameraId;
ToggleButton mTB;
int width = 1280;
int height = 1080;
int framerate = 30; // 帧率
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);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera2);
initView();
}
void initView() {
surfaceView = findViewById(R.id.sfv_camera_2);
surfaceHolder = surfaceView.getHolder();
mTB = findViewById(R.id.tb_code);
mTB.setOnCheckedChangeListener(this);
surfaceHolder.setKeepScreenOn(true);
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCamere2();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
surfaceView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// takePictrue();
}
});
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void initCamere2() {
/**
* camera2 中有些回调方法会在handle中用到,学要自己
*/
HandlerThread handlerThread = new HandlerThread("Camera2");
handlerThread.start();
childHandler = new Handler(handlerThread.getLooper());
mainHandler = new Handler(getMainLooper());
cameraId = "" + CameraCharacteristics.LENS_FACING_FRONT;
imageReader = ImageReader.newInstance(1080, 1920, ImageFormat.JPEG, 10); // 作为预览数据回调中介
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
/**
* 在此方法中可以获得每一帧相关信息
* @param reader
*/
@Override
public void onImageAvailable(ImageReader reader) {
Log.e("camera2","camera2 imageReader");
// cameraDevice.close();
// surfaceView.setVisibility(View.GONE);
Image image = reader.acquireNextImage();
ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
image.close();
}
}, mainHandler);
cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE); // 获取camera管理
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
try {
cameraManager.openCamera(cameraId, stateCallback, mainHandler); // 打开摄像头
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 摄像头操作回调
*/
private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
takePreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
if (null != cameraDevice) {
cameraDevice.close();
cameraDevice = null;
}
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
}
};
/**
* 设置预览
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void takePreview(){
try {
final CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(surfaceHolder.getSurface());
builder.addTarget(imageReader.getSurface());
cameraDevice.createCaptureSession(Arrays.asList(surfaceHolder.getSurface(),imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
if (null == cameraDevice)return;
builder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_AUTO);
builder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
CaptureRequest request = builder.build();
cameraCaptureSession = session;
try {
cameraCaptureSession.setRepeatingRequest(request,null,childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
},childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void takePictrue(){
try {
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
builder.addTarget(imageReader.getSurface());
builder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
builder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
CaptureRequest request = builder.build();
cameraCaptureSession.capture(request,null,childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.e("toggle","toggle ===="+isChecked);
if (isChecked){ // 开始录制
}else { // 停止录制
}
}
}