Android Camera2 API 拍照并保存 PNG 图片示例
在 Android 中,使用 android.hardware.camera2 包来实现相机功能。下面是一个示例的 Activity 代码,点击按钮后调用 CaptureRequest 来拍照并保存为 PNG 图片:
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CAMERA_PERMISSION = 200;
private static final String TAG = "Camera2Capture";
private Button captureButton;
private CameraManager cameraManager;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSession;
private CaptureRequest.Builder captureRequestBuilder;
private File imageFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
captureButton = findViewById(R.id.capture_button);
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
return;
}
try {
cameraManager.openCamera("0", cameraStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
});
}
private CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
cameraDevice = camera;
createCaptureSession();
}
@Override
public void onDisconnected(CameraDevice camera) {
cameraDevice.close();
}
@Override
public void onError(CameraDevice camera, int error) {
cameraDevice.close();
}
};
private CameraCaptureSession.StateCallback captureSessionCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
cameraCaptureSession = session;
startPreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Toast.makeText(MainActivity.this, "Failed to configure camera capture session", Toast.LENGTH_SHORT).show();
}
};
private void createCaptureSession() {
try {
SurfaceTexture surfaceTexture = new SurfaceTexture(1);
surfaceTexture.setDefaultBufferSize(640, 480);
Surface previewSurface = new Surface(surfaceTexture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(previewSurface);
cameraDevice.createCaptureSession(Arrays.asList(previewSurface), captureSessionCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startPreview() {
try {
cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
captureImage();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void captureImage() {
try {
imageFile = createImageFile();
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(ImageReader.newInstance(640, 480, ImageFormat.JPEG, 1).getSurface());
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, 90);
cameraCaptureSession.stopRepeating();
cameraCaptureSession.abortCaptures();
cameraCaptureSession.capture(captureBuilder.build(), captureCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private File createImageFile() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "IMG_" + timeStamp + ".png";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = new File(storageDir, imageFileName);
return imageFile;
}
private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
Toast.makeText(MainActivity.this, "Image captured: " + imageFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
startPreview();
}
};
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
cameraManager.openCamera("0", cameraStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show();
}
}
}
}
在你的项目中,需要在 AndroidManifest.xml 文件中添加相机权限:
<uses-permission android:name="android.permission.CAMERA" />
此外,还需要添加以下权限,以便保存图片到存储中:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
上述示例中,图片将保存在公共图片目录下,你可以根据你的需求修改保存路径。
注意:在 Android 6.0 及以上版本,你需要在运行时请求相机权限。以上示例中已包含相机权限的请求和处理逻辑。
请确保在你的设备上正确配置相机硬件,并适配正确的相机 ID(例如:"0")。
原文地址: https://www.cveoy.top/t/topic/Ngm 著作权归作者所有。请勿转载和采集!