使用Gluon ShareService共享多个文件(image和txt)

时间:2017-11-30 09:26:31

标签: java javafx gluon gluon-mobile

我们想知道如何使用Gluon ShareService共享多个文件(图像和文本文件)。特别是如何与PictureService共享以前拍摄并存储(在图库中)的图像。

但我们需要首先使用路径和图像名称创建一个文件。不幸的是,PictureService会保存图像,图像标题包含拍摄照片时的日期和时间。

我们尝试使用loadImageFromGallery方法获取图像名称,但这会返回void并打开最近的屏幕。

这是我们尝试分享图片的内容:

public void sharePicture() {
    Services.get(PicturesService.class).ifPresent(picturesService -> {
          Image image = picturesService.loadImageFromGallery().get();
      File file= new File("Pictures", image.toString());
      Services.get(ShareService.class).ifPresent(service -> {
        service.share("image/jpg", file);
      });
    });
  }
  • 我们如何用我们想要的标题存储我们想要的图像?
  • 我们如何共享文件和图像?

1 个答案:

答案 0 :(得分:2)

您走在正确的轨道上,结合Charm Down的不同服务,以便从图库中选择图像并进行分享。

但是这种方法存在一个主要问题:您无法轻松地将JavaFX Image转换为File

到目前为止,PicturesService只返回一个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

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

修改

避免内存问题以及减少共享文件大小的可能解决方案(基于此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 
    ...