【发布时间】:2019-11-16 16:08:14
【问题描述】:
我正在尝试从 YUV_420_888 图像中获取 Exif 数据,但它不起作用。我尝试了几种解决方案,例如将图像作为 jpeg 保存到磁盘,将其转换为输入流,但似乎没有任何效果。
我使用 android camera2 api 捕获 YUV_420_888 图像。然后在 OnImageAvailableListener 中,我获取图像并尝试使用 ExifInterface API 读取其 EXIF 数据。但它总是空的。我尝试了 link 中的所有方法来获取正确的字节数组。
这是我的代码:
@Override
public void onImageAvailable(ImageReader imageReader) {
if (!isRecording) {
return;
}
Image image = imageReader.acquireNextImage();
File file = Util.getImagePath(context);
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
outputStream.write(data);
//// This byte array I am making using all the approaches given in this link
https://stackoverflow.com/questions/44022062/converting-yuv-420-888-to-jpeg-and-saving-file-results-distorted-image
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
ExifInterface exifInterface = new ExifInterface(file.getAbsolutePath()); /// This is always empty
int currentIso = (int)exifInterface.getAttributeDouble(ExifInterface.TAG_ISO_SPEED_RATINGS, 0); /// Always 0
} catch (Exception e) {
e.printStackTrace();
}
image.close();
}
编辑:捕获图像的代码:
captureRequest = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequest.addTarget(preview);
captureRequest.addTarget(imageReader.getSurface());
captureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
captureRequest.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
captureRequest.set(CaptureRequest.SENSOR_SENSITIVITY, <MANUAL_ISO>);
captureRequest.set(CaptureRequest.SENSOR_EXPOSURE_TIME, <MANUAL_EXPOSURE>);
mSession.capture(captureRequest.build(), new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
int capturedISO = result.get(CaptureResult.SENSOR_SENSITIVITY);
long timeStamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
/// Save somewhere to be used later
super.onCaptureCompleted(session, request, result);
}
}, backgroundHandler);
【问题讨论】:
-
我认为
YUV_420_888格式不支持Exif 数据。在某些情况下,帧的第一行中有一些元数据,但这因相机而异。您使用的相机型号是什么? -
@Rotem 感谢您的回答。我也有同样的怀疑。我实际上是在使用 Android 的 Camera2 API 在 android 设备中捕捉照片。当我捕获 jpeg 但不能使用 YUV 时,我可以获得 exif 数据。我什至尝试将 YUV 保存为 jpeg 以希望获得 exif 数据,但它没有帮助。如果您可以添加任何输入,那将有很大帮助
-
我没有任何使用 Camera2 API 的经验,也没有使用 android 编程。我确实知道文件系统中的图像(如 JPEG、DNG、Tiff)支持 exif 数据,而不是像
YUV_420_888这样的 RAM 中的 RAW 帧。当将帧捕获到内存而不是磁盘时,可能还有其他 API 用于接收数据。根据文档,您可以使用TotalCaptureResult类。 -
是的,我可以并且我确实使用了它,但是 TotalCaptueResult 没有满足我的用例。我必须以某种方式从图像中获取 exif 数据。
-
@Shivam 您正在尝试做的是,在新一代移动设备中几乎是不可能的。 Camera2 API 的开发考虑到现在的移动设备使用多个摄像头来捕捉单张图片。在这种情况下,将不提供元数据,因为图像不是直接来自物理相机而是来自逻辑平面。如果您捕获此图像,您可以在通过 ExifInterface 保存后在 onImageAvailable 中手动设置元数据 exif = new ExifInterface(mFile.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, "10"); exif.saveAttributes();
标签: android exif android-camera2 yuv