您走在正确的道路上,结合了不同的服务魅力下降,以便从图库中选择图像并共享。
不过,这种方法有一个主要问题:您无法轻松转换 JavaFXImage
into a File
.
到目前为止图片服务仅返回 JavaFX 图像,而不是文件,因此我们需要一种方法将该图像保存到我们可以读取和共享的文件中。
这个过程并不容易,因为在移动设备上我们没有SwingUtilities
.
最初的方法是使用PixelReader
读取图像并获取字节数组实际上不起作用,因为它会给您一个无法读取或共享的大原始文件。
我用过这个solution它利用 PNG 编码器从 JavaFX 图像中获取 png 的字节数组:
PngEncoderFX encoder = new PngEncoderFX(image, true);
byte[] bytes = encoder.pngEncode();
然后,我将该字节数组保存到公共存储文件夹中的一个文件中(以便可以共享),我可以使用“StorageService”进行检索:
private File getImageFile(Image image) {
if (image == null) {
return null;
}
// 1. Encode image to png
PngEncoderFX encoder = new PngEncoderFX(image, true);
byte[] bytes = encoder.pngEncode();
// 2.Write byte array to a file in public storage
File root = Services.get(StorageService.class)
.flatMap(storage -> storage.getPublicStorage("Pictures"))
.orElse(null);
if (root != null) {
File file = new File(root, "Image-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("uuuuMMdd-HHmmss")) + ".png");
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytes);
return file;
} catch (IOException ex) {
System.out.println("Error: " + ex);
}
}
return null;
}
现在,您可以致电PicturesService
,检索图像,将其保存到文件中,最后share it:
Services.get(PicturesService.class).ifPresent(pictures -> {
// 1. Retrieve picture from gallery
pictures.loadImageFromGallery().ifPresent(image -> {
// 2. Convert image to file
File imageFile = getImageFile(image);
// 3. Share file
if (imageFile != null) {
Services.get(ShareService.class).ifPresent(share -> {
share.share("image/png", imageFile);
});
}
});
});
请注意,如果您尝试对大图像进行编码,则可能会遇到内存问题。
无论如何,如果 PicturesService 首先返回一个文件,那么所有过程都可以简化。如果您想提出问题,您可以这样做here.
EDIT
避免内存问题并减少共享文件大小的可能解决方案,并在此基础上solution,如果原始图像超过一定大小,则缩小原始图像,就像在 PicturesService 的 iOS 实现中已经完成的那样:
private Image scaleImage(Image source) {
// Possible limit based on memory limitations
double maxResolution = 1280;
double width = source.getWidth();
double height = source.getHeight();
double targetWidth = width;
double targetHeight = height;
if (width > maxResolution || height > maxResolution) {
double ratio = width/height;
if (ratio > 1) {
targetWidth = maxResolution;
targetHeight = targetWidth/ ratio;
}
else {
targetHeight = maxResolution;
targetWidth = targetHeight * ratio;
}
}
ImageView imageView = new ImageView(source);
imageView.setPreserveRatio(true);
imageView.setFitWidth(targetWidth);
imageView.setFitHeight(targetHeight);
return imageView.snapshot(null, null);
}
这个方法现在可以用在getImageFile()
:
// 1 Scale image to avoid memory issues
Image scaledImage = scaleImage(image);
// 2. Encode image to png
PngEncoderFX encoder = new PngEncoderFX(scaledImage, true);
byte[] bytes = encoder.pngEncode();
// 3. Write byte array to a file in public storage
...