【发布时间】:2020-10-20 05:54:34
【问题描述】:
我正在使用最新的相机X
def camerax_version = "1.0.0-beta11"
我可以使用以下代码拍照并将图像保存到文件夹中的外部存储
File photoFile = new File(outputDirectory, "Image_" + System.currentTimeMillis() + ".jpg");
ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build();
imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(getBaseContext()), new ImageCapture.OnImageSavedCallback() {
@Override
public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
Uri.fromFile(photoFile);
Toast.makeText(getBaseContext(), "Image Saved" + photoFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
}
@Override
public void onError(@NonNull ImageCaptureException exception) {
Toast.makeText(getBaseContext(), "Error Saving Image" + photoFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
}
});
现在的重点是如何在将图像保存到外部存储之前提取图像。我想要实现的是捕获多个图像并将其保存在缓冲区中并将这些图像发送到下一个 Activity 并使用列表或其他方式将它们显示在 imageView 中。
现在这可以在imageCapture 上使用onImageCapturedCallback 来实现,这给了我一个ImageProxy,然后它必须转换为字节数组。但是这个过程只适用于小尺寸和单一图像。
如何才能为更高分辨率和多张图片实现这一目标。
下面是我用来捕获ImageProxy 并将 imageCapture 设置为“YUV”的代码,遗憾的是它根本不起作用
imageCapture.takePicture(ContextCompat.getMainExecutor(getBaseContext()), new ImageCapture.OnImageCapturedCallback() {
@Override
public void onCaptureSuccess(@NonNull ImageProxy image) {
super.onCaptureSuccess(image);
@SuppressLint("UnsafeExperimentalUsageError") Image cimage = image.getImage();
Image.Plane[] planes = cimage.getPlanes();
ByteBuffer yBuffer = planes[0].getBuffer();
ByteBuffer uBuffer = planes[1].getBuffer();
ByteBuffer vBuffer = planes[2].getBuffer();
int ySize = yBuffer.remaining();
int uSize = uBuffer.remaining();
int vSize = vBuffer.remaining();
byte[] nv21 = new byte[ySize + uSize + vSize];
yBuffer.get(nv21,0,ySize);
vBuffer.get(nv21,ySize,vSize);
uBuffer.get(nv21,ySize + vSize,uSize);
YuvImage yuvImage = new YuvImage(nv21,ImageFormat.NV21,cimage.getWidth(),cimage.getHeight(),null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0,0,yuvImage.getWidth(),yuvImage.getHeight()),100,out);
byte[] imageBytes = out.toByteArray();
Intent intent = new Intent(MainActivity.this,MainActivity2.class);
intent.putExtra("image",imageBytes);
MainActivity.this.startActivity(intent);
}
@Override
public void onError(@NonNull ImageCaptureException exception) {
super.onError(exception);
}
});
我可以将图片添加到ArrayList,然后发送过来吗?
提前致谢..
【问题讨论】:
-
我建议将图像转换为位图,然后使用 ImageProxy.close 获取下一帧并捕获它,然后将所有位图保存到 ArrayList 中,然后您可以显示它们。
-
@mmdrezabaqalpour 那么我可以使用 Intent.putExtra(); 将这些位图发送到新 Activity 吗?
-
是的,只要位图是一个包裹对象,您就可以按意图发送它。 intent.putParcelableArrayListExtra()
-
@mmdrezabaqalpour 在 ImageCaptureCallback 期间,我必须将 imageCapture 设置为 YUV 格式才能将图像转换为位图。这会显着降低图像质量。有什么办法吗..
-
如果对您有用,我会发布一些方法作为答案。
标签: java android android-studio android-camerax