[英]Android CAMERA 2 API captures 0kb images & gives a full white preview. Shows no errors or warnings on logcat
我将Android CAMERA 2 API用于支持我的应用程序中的camera2支持的手机。 效果很好,但有时会捕获0kb图像并提供全白预览 。 在logcat上不显示任何错误或警告。 以下是我的相机图像捕获和保存代码:
protected void takePictureViaCamera2() {
if (null == cameraDevice) {
Log.e(TAG, "cameraDevice is null");
return;
}
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if (characteristics != null) {
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
}
int width = 640;
int height = 480;
if (jpegSizes != null && 0 < jpegSizes.length) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
//final File file = new File(Environment.getExternalStorageDirectory()+"/pic.jpg");
final File file = createImageFile();
final String checkPath = file.getParent();
Log.e("checkPath", checkPath);
//photoFile = createImageFile();
//photoFilePath = photoFile.getParent();
//Log.e("photoFilePath", photoFilePath);
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("readerListenerFNF_EX", e + "");
} catch (IOException e) {
e.printStackTrace();
Log.e("readerListenerIO_EX", e + "");
} catch (Exception e) {
e.printStackTrace();
Log.e("readerListener_EX", e + "");
} finally {
if (image != null) {
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream output = null;
try {
output = new FileOutputStream(file);
//output = new FileOutputStream(photoFile);
output.write(bytes);
} finally {
if (null != output) {
output.close();
}
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(TravelChargesCamera2Activity.this, "Saved***:" + file, Toast.LENGTH_SHORT).show();
createCameraPreview();
closeCamera();
Thread thread = new Thread() {
@Override
public void run() {
try {
synchronized (this) {
wait(5000);
runOnUiThread(new Runnable() {
@Override
public void run() {
toolbar.setVisibility(View.VISIBLE);
header.setVisibility(View.VISIBLE);
assessorTraveldetails_scroll.setVisibility(View.VISIBLE);
camera2Layout.setVisibility(View.GONE);
try {
if (!file.getParentFile().isDirectory()) {
travelDirectory = new File(checkPath);
Log.e("travelDir==created==", travelDirectory + "");
} else {
travelDirectory = file.getParentFile();
Log.e("travelDir==exists==", travelDirectory + "");
}
files = travelDirectory.listFiles();
Log.e("files", files + "");
// removes old images from view
// prevents display duplication
travelGallery.removeAllViews();
// loop displays the photos captured on Horizontal ScrollView
for (File picFile : files) {
travelGallery.addView(insertPhoto(picFile.getAbsolutePath()));
byte[] byteArray = ImageUtils.fileToByteArray(file);
Log.e("byteArray", byteArray + "");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("file", e + "");
}
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("InterruptedException", e + "");
} catch (Exception e) {
e.printStackTrace();
Log.e("Exception", e + "");
}
}
};
thread.start();
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
Log.e("CameraAccessException", e + "");
} catch (Exception e) {
e.printStackTrace();
Log.e("takePictureViaCamera2", e + "");
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String uniqueId = UUID.randomUUID().toString();
String imageFileName = "CAP_" + timeStamp + "_" + uniqueId;
String bCode = "";
masterMap = (LinkedTreeMap) gson.fromJson(batchMasterObject.getMasterJson(), Object.class);
auditMap = (LinkedTreeMap) masterMap.get("2001");
if ((auditMap.get("batchCode") != null && !auditMap.get("batchCode").equals(""))) {
bCode = auditMap.get("batchCode").toString();
} else if (auditMap.get("cbc") != null && !auditMap.get("cbc").equals("")) {
bCode = auditMap.get("cbc").toString();
}
File storageDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "/" + bCode + "/Travel/");
if (!storageDir.exists()) {
storageDir.mkdirs();
}
String checkPath = storageDir.getPath();
Log.e("checkPath", checkPath);
Toast.makeText(getApplicationContext(), checkPath, Toast.LENGTH_LONG).show();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = storageDir.getAbsolutePath();
return image;
}
有人可以帮忙吗?
注意:相机会按预期捕获和存储图像文件,但是文件大小为0kb。 在手机或PC上打开图片文件时,显示“不支持的格式”
好像您将最终的JPEG捕获作为第一帧。
这意味着相机的自动曝光例程没有任何时间可用(因为您正在抓取第一帧),因此将使用硬编码到相机驱动程序中的初始设置来捕获图像。 这可能适用于某些场景,但在另一些场景中,图像将太亮或太暗。
为了获得最佳效果,您应该先让相机测光一会儿,直到自动曝光和自动对焦收敛为止。
通常,可以通过设置低分辨率预览输出(例如,使用SurfaceTexture)并运行一两秒(或等到CaptureResult的AE_STATE为CONVERGED来完成)。 然后发出JPEG捕获。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.