致电
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("")它列出了两个文件夹: 胶子,图片。
我如何正确访问它?
答案 0 :(得分:3)
正如前面在question中所讨论的那样,在移动设备上没有Swing或AWT,所以一旦你有了一个JavaFX图像,要检索它,就不能使用SwingFXUtils
。
上述问题中提出的解决方案适用于Android,因为您可以轻松获取文件。相反,在iOS上,该文件位于图库中,当前的Charm Down PicturesService
无法访问图库。
而不是修改该服务(使用本地代码,如one),从JavaFX Image
获取可以发送到Web服务的byteArray的想法基于两个步骤:< / p>
如果检查PicturesService::takePhoto
的iOS实现,则iOS本机层中的图像将通过Base64 encoding和decoding发送到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);
解决方案2
如果要将字节数组从PixelReader::getPixels
转换为BufferedImage
,那将无效:字节数组不同。
所以你需要使用缓冲图像能够处理的东西。
看一下SwingFXUtils
实现,它改为使用int数组。
所以这是另一种可能性:
// 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 int array
PixelReader pixelReader = image.getPixelReader();
int width = (int) image.getWidth();
int height = (int) image.getHeight();
int[] data = new int[width * height];
pixelReader.getPixels(0, 0, width, height, PixelFormat.getIntArgbPreInstance(), data, 0, width);
// 2. int array to byte array
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(data);
// 3. Encode to String
String encoded = Base64.getEncoder().encodeToString(byteBuffer.array());
// 4. send string...
}
}
现在你必须解码字符串,获取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);