android 中无法使用自定义相机将捕获的图像保存在文件夹中
Can't save captured image in folder using custom camera in android
我有一个带有 自定义相机 的简单应用程序,但是当我拍照时,我无法将 拍摄的图像 保存在 Downloads 模拟器中的文件夹,而不是创建的空白文件夹我不知道为什么以及我的代码中的错误在哪里。我搜索了答案,但没有找到有用的答案。
你能帮忙吗?
Image Reader
final ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurface = new ArrayList<>();
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
builder.addTarget(reader.getSurface());
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
builder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
final ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
Image mCapturedImage;
mCapturedImage = imageReader.acquireLatestImage();
mFile = getActivity().getExternalFilesDir(null);
ImageSaver saver = new ImageSaver(mCapturedImage,getActivity().getExternalFilesDir(null));
mBackgroundHandler.post(saver);
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
showSnackBar("Image saved", Snackbar.LENGTH_LONG);
createCameraPreview();
}
};
ImageSaver class
private static class ImageSaver implements Runnable {
private final File mFile;
private Image mImage;
ImageSaver(Image image, File file) {
mImage = image;
mFile = file;
}
@Override
public void run() {
if (mImage != null) {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream output = null;
try {
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String format = s.format(new Date());
String fileName = format+".jpg";
File file = new File(mFile, "image_" + fileName);
output = new FileOutputStream(file);
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
你的代码做的是正确的,所以将图像文件保存到设备,但它保存到此处返回路径的结果:
mFile = getActivity().getExternalFilesDir(null);
外部文件目录可能指向 myapp/data/data,这是为您的应用程序写入外部存储的文件保留的 'sandbox' 数据区域。这与下载文件夹不同,后者将文件保存到 phone.
上的共享(关于沙箱之外)数据区域
如果您想保存到“下载”,您可能必须将图像写入外部网站,然后将 https:// 路径传递给 ViewIntent,它会在浏览器会话中显示您的图像,并给您从那里下载图像的选项。
在您的代码中,您有:
mFile = getActivity().getExternalFilesDir(null);
但我没有看到图像中 mFile 的声明位置 Reader。在你的另一个 class 中,你将它定义为一个文件。如果 mFile 是一个文件,那么你可能应该这样做:
String mPath = getActivity().getExternalFilesDir(null);
File mFile = new File(mPath + "/temp.jpg");
// but I don't think you need to create a file, just use the path
ImageSaver saver = new ImageSaver(mCapturedImage,mPath);
我有一个带有 自定义相机 的简单应用程序,但是当我拍照时,我无法将 拍摄的图像 保存在 Downloads 模拟器中的文件夹,而不是创建的空白文件夹我不知道为什么以及我的代码中的错误在哪里。我搜索了答案,但没有找到有用的答案。
你能帮忙吗?
Image Reader
final ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurface = new ArrayList<>();
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
builder.addTarget(reader.getSurface());
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
builder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
final ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
Image mCapturedImage;
mCapturedImage = imageReader.acquireLatestImage();
mFile = getActivity().getExternalFilesDir(null);
ImageSaver saver = new ImageSaver(mCapturedImage,getActivity().getExternalFilesDir(null));
mBackgroundHandler.post(saver);
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
showSnackBar("Image saved", Snackbar.LENGTH_LONG);
createCameraPreview();
}
};
ImageSaver class
private static class ImageSaver implements Runnable {
private final File mFile;
private Image mImage;
ImageSaver(Image image, File file) {
mImage = image;
mFile = file;
}
@Override
public void run() {
if (mImage != null) {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream output = null;
try {
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String format = s.format(new Date());
String fileName = format+".jpg";
File file = new File(mFile, "image_" + fileName);
output = new FileOutputStream(file);
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
你的代码做的是正确的,所以将图像文件保存到设备,但它保存到此处返回路径的结果:
mFile = getActivity().getExternalFilesDir(null);
外部文件目录可能指向 myapp/data/data,这是为您的应用程序写入外部存储的文件保留的 'sandbox' 数据区域。这与下载文件夹不同,后者将文件保存到 phone.
上的共享(关于沙箱之外)数据区域如果您想保存到“下载”,您可能必须将图像写入外部网站,然后将 https:// 路径传递给 ViewIntent,它会在浏览器会话中显示您的图像,并给您从那里下载图像的选项。
在您的代码中,您有:
mFile = getActivity().getExternalFilesDir(null);
但我没有看到图像中 mFile 的声明位置 Reader。在你的另一个 class 中,你将它定义为一个文件。如果 mFile 是一个文件,那么你可能应该这样做:
String mPath = getActivity().getExternalFilesDir(null);
File mFile = new File(mPath + "/temp.jpg");
// but I don't think you need to create a file, just use the path
ImageSaver saver = new ImageSaver(mCapturedImage,mPath);