CameraManager 拍照代码
时间: 2023-07-02 22:11:24 浏览: 151
以下是使用 CameraManager 进行拍照的代码示例:
首先,在 AndroidManifest.xml 文件中添加相机权限:
```xml
<uses-permission android:name="android.permission.CAMERA" />
```
然后,在需要拍照的 Activity 中,定义 CameraManager 对象和相机预览视图:
```java
private CameraManager cameraManager;
private CameraPreview cameraPreview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取 CameraManager 实例
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
// 初始化相机预览视图
cameraPreview = findViewById(R.id.camera_preview);
cameraPreview.setCameraManager(cameraManager);
}
```
在布局文件中添加相机预览视图:
```xml
<com.example.camera.CameraPreview
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```
接下来,实现拍照功能。在拍照之前,需要先打开相机并启动预览:
```java
private void startCamera() {
try {
// 获取相机列表中的第一个相机
String cameraId = cameraManager.getCameraIdList()[0];
// 打开相机并设置预览视图
cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 启动相机预览
cameraPreview.setCamera(camera);
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
camera.close();
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
camera.close();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
```
在拍照时,可以通过调用相机的 takePicture() 方法实现:
```java
private void takePicture() {
// 获取当前相机
CameraDevice camera = cameraPreview.getCamera();
// 创建拍照请求
CaptureRequest.Builder captureRequestBuilder;
try {
captureRequestBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(cameraPreview.getOutputSurface());
} catch (CameraAccessException e) {
e.printStackTrace();
return;
}
// 设置拍照参数
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// 发送拍照请求
try {
camera.createCaptureSession(Collections.singletonList(cameraPreview.getOutputSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
session.capture(captureRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
// 拍照完成后的处理
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 配置会话失败的处理
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
```
完整的 CameraPreview 类和布局文件示例:
```java
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder surfaceHolder;
private CameraDevice cameraDevice;
private CameraManager cameraManager;
private ImageReader imageReader;
private Size previewSize;
public CameraPreview(Context context, AttributeSet attrs) {
super(context, attrs);
// 初始化 SurfaceHolder
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// Surface 创建时打开相机
startCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Surface 改变时重新启动预览
stopPreview();
startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface 销毁时关闭相机
stopCamera();
}
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
}
public void setCamera(CameraDevice cameraDevice) {
this.cameraDevice = cameraDevice;
}
public CameraDevice getCamera() {
return cameraDevice;
}
public Surface getOutputSurface() {
return imageReader.getSurface();
}
private void startCamera() {
try {
// 获取相机列表中的第一个相机
String cameraId = cameraManager.getCameraIdList()[0];
// 打开相机并设置预览视图
cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 启动相机预览
cameraDevice = camera;
startPreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
camera.close();
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
camera.close();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void stopCamera() {
// 关闭相机
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
}
private void startPreview() {
try {
// 获取相机的预览尺寸
previewSize = getPreviewSize();
// 创建 ImageReader 对象用于拍照
imageReader = ImageReader.newInstance(previewSize.getWidth(), previewSize.getHeight(), ImageFormat.JPEG, 1);
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
// 获取拍照的图片
Image image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
// 保存图片到文件系统
File file = new File(getContext().getExternalFilesDir(null), "photo.jpg");
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(file);
outputStream.write(data);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 关闭 Image 对象
image.close();
}
}, null);
// 创建预览请求
CaptureRequest.Builder previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(getHolder().getSurface());
// 创建拍照请求
CaptureRequest.Builder captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(imageReader.getSurface());
// 设置自动对焦和自动曝光
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 设置预览请求为连续自动对焦和自动曝光模式
cameraDevice.createCaptureSession(Arrays.asList(getHolder().getSurface(), imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
// 发送预览请求
session.setRepeatingRequest(previewRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 配置会话失败的处理
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void stopPreview() {
// 停止预览
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
}
private Size getPreviewSize() throws CameraAccessException {
// 获取相机支持的所有输出尺寸
StreamConfigurationMap map = cameraManager.getCameraCharacteristics(cameraDevice.getId()).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = map.getOutputSizes(SurfaceHolder.class);
// 选择与屏幕尺寸最接近的预览尺寸
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
int minDiff = Integer.MAX_VALUE;
Size bestSize = null;
for (Size size : sizes) {
int diff = Math.abs(size.getWidth() - screenWidth) + Math.abs(size.getHeight() - screenHeight);
if (diff < minDiff) {
minDiff = diff;
bestSize = size;
}
}
return bestSize;
}
}
```
```xml
<com.example.camera.CameraPreview
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```
阅读全文