gpt4 book ai didi

android - 使用 Camera2 API 的图片真的很暗

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:37:13 25 4
gpt4 key购买 nike

我在 Android 上工作,我试图在不显示任何预览的情况下拍摄图片。我试图通过上课来简化这个过程。它正在工作,但所有图片都非常暗。这是我的课:

public class Cam {
private Context context;
private CameraManager manager;
private CameraDevice camera;
private CameraCaptureSession session;
private ImageReader reader;
public static String FRONT="-1";
public static String BACK="-1";
private boolean available=true;
private String filepath;

private static final String NO_CAM = "No camera found on device!";
private static final String ERR_CONFIGURE = "Failed configuring session";
private static final String ERR_OPEN = "Can't open the camera";
private static final String CAM_DISCONNECT = "Camera disconnected";
private static final String FILE_EXIST = "File already exist";

private static final 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);
}

public Cam(Context context) throws CameraAccessException {
this.context = context;
this.manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String ids[] = manager.getCameraIdList();
if(ids.length==2){
BACK=ids[0];
FRONT=ids[1];
}
else if(ids.length==1){
BACK=ids[0];
}
else{
available=false;
throw new CameraAccessException(-1, NO_CAM);
}
}

public void takePicture(String camId, String filepath) throws CameraAccessException {
if(available){
this.filepath=filepath;
StreamConfigurationMap map = manager.getCameraCharacteristics(camId).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size largest = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea());
reader=ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, 1);
reader.setOnImageAvailableListener(imageListener, null);
manager.openCamera(camId, cameraStateCallback, null);
}
else
throwError(NO_CAM);
}

private CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
Cam.this.camera=camera;
try {
camera.createCaptureSession(Collections.singletonList(reader.getSurface()), sessionStateCallback, null);
} catch (CameraAccessException e) {
throwError(e.getMessage());
}
}

@Override
public void onDisconnected(CameraDevice camera) {
throwError(CAM_DISCONNECT);
}

@Override
public void onError(CameraDevice camera, int error) {
throwError(ERR_OPEN);
}
};

private CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
Cam.this.session=session;
try {
CaptureRequest.Builder request = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
request.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
request.addTarget(reader.getSurface());
int rotation = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
request.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
session.capture(request.build(), captureCallback, null);
} catch (CameraAccessException e) {
throwError(e.getMessage());
}
}

@Override
public void onConfigureFailed(CameraCaptureSession session) {
throwError(ERR_CONFIGURE);
}
};

private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
throwError(failure.toString());
}
};

private ImageReader.OnImageAvailableListener imageListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
try {
File file = saveImage(image);
// Send file via a listener
closeCamera();
} catch (IOException e) {
throwError(e.getMessage());
}
reader.close();
}
};

private File saveImage(Image image) throws IOException {
File file = new File(filepath);
if (file.exists()) {
throwError(FILE_EXIST);
return null;
}
else {
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream output = new FileOutputStream(file);
output.write(bytes);
image.close();
output.close();
return file;
}
}

static class CompareSizesByArea implements Comparator<Size> {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
}
}

private void closeCamera(){
if(session!=null) {session.close();}
if(reader!=null) {reader.close();}
if(camera!=null) {camera.close();}
}

然后我在我的 Activity 中调用 Cam 对象:

Cam cam = new Cam(MainActivity.this);
cam.takePicture(Cam.BACK, "/sdcard/pic.jpg");

当图片可用时,监听器会阻止 MainActivity,但我删除了代码以清除一点。

我不知道我做错了什么,图片真的很暗。也许是一面旗帜或其他东西......任何帮助将不胜感激。

编辑: worker 类(Class):https://github.com/omaflak/Android-Camera2-Library/blob/master/ezcam/src/main/java/me/aflak/ezcam/EZCam.java

示例:https://github.com/omaflak/Android-Camera2-Library/blob/master/app/src/main/java/me/aflak/libraries/MainActivity.java

最佳答案

如果您发送给相机的唯一捕获请求是最终图片请求,这不足为奇。

相机自动曝光、对焦和白平衡例程通常需要一两秒的流缓冲才能收敛到良好的结果。

虽然您不需要在屏幕上绘制预览,但这里最简单的方法是首先针对虚拟 SurfaceTexture 运行重复请求一两秒钟,然后触发 JPEG 捕获。您可以只流式传输 JPEG 捕获,但 JPEG 捕获速度很慢,因此您需要更长的时间来收敛(此外,与典型的预览相比,相机实现更可能存在重复 JPEG 捕获和获得良好曝光的错误) .

因此,创建一个带有随机纹理 ID 参数的虚拟 SurfaceTexture:

private SurfaceTexture mDummyPreview = new SurfaceTexture(1);
private Surface mDummySurface = new Surface(mDummyPreview);

并将 Surface 包含在您的 session 配置中。配置 session 后,创建一个以虚拟预览为目标的预览请求,并在 N 个捕获结果进来后,提交您想要的 JPEG 的捕获请求。您可能想要尝试使用 N,但大概 ~30 帧就足够了。

请注意,您还没有处理:

  • 锁定自动对焦以确保您的 JPEG 图像清晰
  • 运行 AE 预捕获以允许闪光测光,如果你想允许使用闪光灯的话
  • 通过某种方式让用户知道他们将捕获什么,因为没有预览,他们无法将设备对准任何目标。

AF 锁定和预捕获触发序列包含在此处的 Camera2Basic 示例中:https://github.com/googlesamples/android-Camera2Basic ,所以您可以看看它们的作用。

关于android - 使用 Camera2 API 的图片真的很暗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31925769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com