Javafx getPublicStorage(“图片”)不列出任何文件

Javafx getPublicStorage(“图片”)不列出任何文件,javafx,gluon-mobile,Javafx,Gluon Mobile,召唤 File picturesDir = Services.get(StorageService.class) .flatMap(s -> s.getPublicStorage("Pictures")) .orElseThrow(() -> new RuntimeException("Error retrieving public storage")); for (File pic : picturesDir.listFiles()

召唤

File picturesDir = Services.get(StorageService.class)
            .flatMap(s -> s.getPublicStorage("Pictures"))
            .orElseThrow(() -> new RuntimeException("Error retrieving public storage")); 
for (File pic : picturesDir.listFiles()) {
        System.out.println("file " + pic.getName());
}
没有列出任何文件。我认为它应该列出iPhone上我的图像库中的所有文件

调用s.getPublicStorage(“”)时,它会列出两个文件夹: 胶子,图片


如何正确访问它?

正如前面所讨论的,在移动设备上没有Swing或AWT,因此一旦有了JavaFX映像,就不能使用
SwingFXUtils

上述问题中提出的解决方案可以在Android上运行,因为您可以轻松获取文件。相反,在iOS上,文件位于多媒体资料中,当前的Charm Down
PictureService
无法访问多媒体资料

与修改该服务(使用类似的本机代码)不同,从JavaFX
Image
获取可发送到web服务的byteArray的想法基于两个步骤:

  • 以字节数组的形式获取图像像素
  • 将字节数组编码为字符串
如果检查iOS实现的
PictureService::takePhoto
,则来自iOS本机层的图像将通过Base64和发送到JavaFX层

解决方案1

这段代码对我来说很有用:

// Take a photo and add image to imageView
Button button = new Button("Take Photo");
button.setOnAction(e ->
    Services.get(PicturesService.class)
        .ifPresent(s -> s.takePhoto(false).ifPresent(imageView::setImage)));

// Encode image
imageView.imageProperty().addListener((obs, ov, image) -> {
    if (image != null) {
        // 1. image to byte array
        PixelReader pixelReader = image.getPixelReader();
        int width = (int) image.getWidth(); 
        int height = (int) image.getHeight(); 
        byte[] buffer = new byte[width * height * 4]; 
        pixelReader.getPixels(0, 0, width, height, PixelFormat.getByteBgraInstance(), buffer, 0, width * 4); 

        // 2. Encode to String
        String encoded = Base64.getEncoder().encodeToString(buffer);

        // 3. send string...
    }
} 
您可以通过反转这些步骤并使用编码字符串创建图像来检查流程是否正常工作:

byte[] imageBytes = Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));

WritablePixelFormat<ByteBuffer> wf = PixelFormat.getByteBgraInstance();
WritableImage writableImage = new WritableImage(width, height);
PixelWriter pixelWriter = writableImage.getPixelWriter();
pixelWriter.setPixels(0, 0, width, height, wf, imageBytes, 0, width * 4);

imageView.setImage(writableImage);
现在,您必须解码字符串,获取int数组并创建缓冲图像:

// 1. Decode string
byte[] imageBytes = Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));

// 2. get int array
ByteBuffer byteBuffer2 = ByteBuffer.wrap(imageBytes);
IntBuffer intBuffer2 = byteBuffer2.asIntBuffer();
int[] imageData = new int[intBuffer2.limit()];
intBuffer2.get(imageData);

// 3. create buffered image
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
bufferedImage.setRGB(0, 0, width, height, imageData, 0, width);

如前所述,在移动设备上没有Swing或AWT,因此一旦有了JavaFX图像,就不能使用
SwingFXUtils

上述问题中提出的解决方案可以在Android上运行,因为您可以轻松获取文件。相反,在iOS上,文件位于多媒体资料中,当前的Charm Down
PictureService
无法访问多媒体资料

与修改该服务(使用类似的本机代码)不同,从JavaFX
Image
获取可发送到web服务的byteArray的想法基于两个步骤:

  • 以字节数组的形式获取图像像素
  • 将字节数组编码为字符串
如果检查iOS实现的
PictureService::takePhoto
,则来自iOS本机层的图像将通过Base64和发送到JavaFX层

解决方案1

这段代码对我来说很有用:

// Take a photo and add image to imageView
Button button = new Button("Take Photo");
button.setOnAction(e ->
    Services.get(PicturesService.class)
        .ifPresent(s -> s.takePhoto(false).ifPresent(imageView::setImage)));

// Encode image
imageView.imageProperty().addListener((obs, ov, image) -> {
    if (image != null) {
        // 1. image to byte array
        PixelReader pixelReader = image.getPixelReader();
        int width = (int) image.getWidth(); 
        int height = (int) image.getHeight(); 
        byte[] buffer = new byte[width * height * 4]; 
        pixelReader.getPixels(0, 0, width, height, PixelFormat.getByteBgraInstance(), buffer, 0, width * 4); 

        // 2. Encode to String
        String encoded = Base64.getEncoder().encodeToString(buffer);

        // 3. send string...
    }
} 
您可以通过反转这些步骤并使用编码字符串创建图像来检查流程是否正常工作:

byte[] imageBytes = Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));

WritablePixelFormat<ByteBuffer> wf = PixelFormat.getByteBgraInstance();
WritableImage writableImage = new WritableImage(width, height);
PixelWriter pixelWriter = writableImage.getPixelWriter();
pixelWriter.setPixels(0, 0, width, height, wf, imageBytes, 0, width * 4);

imageView.setImage(writableImage);
现在,您必须解码字符串,获取int数组并创建缓冲图像:

// 1. Decode string
byte[] imageBytes = Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));

// 2. get int array
ByteBuffer byteBuffer2 = ByteBuffer.wrap(imageBytes);
IntBuffer intBuffer2 = byteBuffer2.asIntBuffer();
int[] imageData = new int[intBuffer2.limit()];
intBuffer2.get(imageData);

// 3. create buffered image
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
bufferedImage.setRGB(0, 0, width, height, imageData, 0, width);

如果查看存储服务的iOS,您会注意到存储是应用程序的本地存储(请参阅使用
NSDocumentDirectory
)。虽然Android有一些公共文件夹(例如,
sdcard/Pictures
),但iOS不允许,因此StorageService实现在这种情况下会产生不同的结果。ok。因此,当我使用PictureService保存了一个图像后,我如何才能在ios上访问该文件本身,而不是作为loadImageFromGallery的图像?你能给我一个这个方向的提示吗?为什么不通过loadimagefromgallery访问呢?这将给我一个图像,这将是罚款。但我无法将其转换为file/ByteArrayInputStream,然后将其上载到Web服务。这是最终的结果,也许能提供更多的背景信息,说明需要解决的问题。再次感谢您的帮助。如果您查看存储服务的iOS,您会注意到该存储是应用程序的本地存储(请参阅使用
NSDocumentDirectory
)。虽然Android有一些公共文件夹(例如,
sdcard/Pictures
),但iOS不允许,因此StorageService实现在这种情况下会产生不同的结果。ok。因此,当我使用PictureService保存了一个图像后,我如何才能在ios上访问该文件本身,而不是作为loadImageFromGallery的图像?你能给我一个这个方向的提示吗?为什么不通过loadimagefromgallery访问呢?这将给我一个图像,这将是罚款。但我无法将其转换为file/ByteArrayInputStream,然后将其上载到Web服务。这是最终的结果,也许能提供更多的背景信息,说明需要解决的问题。再次感谢您的帮助。谢谢您的帮助!我尝试了你的解决方案,运行良好-这意味着我可以再次编码和解码,以在imageView中设置图像。根据我的理解,我应该能够做ByteArrayInputStream bis=newbytearrayinputstream(imageBytes);BuffereImage image=ImageIO.read(bis);但图像是空的。获取BuffereImage缺少的部分是什么?我问这个问题是因为我认为Base64编码是错误的。。。我已将字符串发送到我的Web服务器并在那里解码,但没有查看。因此,我尝试在gluon mobile上获得一个BuffereImage,如上所述,但它为空(在webeservice上)。意味着它无法理解接收到的数据。希望在这方面得到一些提示和更多启示。谢谢。我已经用一个新的解决方案编辑了我的答案,它将允许你创建一个BuffereImage。让我知道这是否对你有效。嗨,何塞。最后,我用你提供的信息解决了这个问题。非常感谢@JoséPereda如果我从DB blob中检索文件,该方法仍然有效吗?我不知道图像的属性(宽度和高度)。谢谢你的帮助!我尝试了你的解决方案,运行良好-这意味着我可以再次编码和解码,以在imageView中设置图像。根据我的理解,我应该能够做ByteArrayInputStream bis=newbytearrayinputstream(imageBytes);BuffereImage image=ImageIO.read(bis);但图像是空的。获取BuffereImage缺少的部分是什么?我问这个问题是因为我认为Base64编码是错误的。。。我已将字符串发送到我的Web服务器并在那里解码,但没有查看。所以我试着在上面的gluon mobile上获得一个BuffereImage,但是它是空的(在w