2017-02-04 6 views
0

не CallinggetPublicStorage ("Изображение") не содержит список файлов не

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 ("") содержит две папки: gluon, Pictures.

Как я могу получить к нему доступ правильно?

+0

Если вы посмотрите на прошивке [реализации] (https: // Bitbucket.org/gluon-oss/charm-down/src/1942aa27c6b60d890511667cf64c3f9d8a0e69b6/plugins/plugin-storage/ios/src/main/native/Storage.m? at = default & fileviewer = file-view-default # Storage.m-52) из Службы хранения вы заметите, что хранилище локально для вашего приложения (см. Использование 'NSDocumentDirectory'). Хотя у Android есть несколько общих папок (т. Е. 'Sdcard/Pictures'), iOS не позволяет этого, поэтому реализация StorageService приводит к различным результатам в этом случае. –

+0

ОК. поэтому, когда я сохранил изображение с помощью функции picturesservice, как я могу получить доступ к самому файлу - не как изображение с loadImageFromGallery - на ios? можете ли вы дать мне подсказку в этом направлении. – tonimaroni

+0

Почему бы не получить доступ через загрузку из галереи? это даст мне изображение, которое будет хорошо. но я не могу преобразовать его в файл/ByteArrayInputStream, который затем можно загрузить в веб-сервис. Это окончательный результат, чтобы дать, возможно, более подробную информацию о том, что нужно решить. спасибо за любую помощь снова. – tonimaroni

ответ

3

Как обсуждалось ранее в этом документе question, на мобильном телефоне нет ни Swing, ни AWT, поэтому, как только вы получите изображение JavaFX, вы можете его использовать, вы не можете использовать SwingFXUtils.

Решение, предложенное в упомянутом вопросе, работает на Android, так как вы можете легко получить файл. На iOS, напротив, файл находится в галерее, и текущий Charm Down PicturesService не имеет доступа к галерее.

Вместо того, чтобы модифицировать эту услугу (с машинным кодом, как этот one), идея, чтобы получить ByteArray, с помощью JavaFX Image, который можно отправить на веб-сервиса на основе двух этапов:

  • Получить пиксели изображения в виде байтового массива
  • Кодировать массив байтов в строку.

Если проверка реализации IOS для PicturesService::takePhoto, образ из родного слоя IOS отправляется к слою JavaFX с помощью Base6 и decoding.

Решение 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... 
    } 
} 

Теперь вам придется декодировать строку, получить целочисленный массив и создать буферизованное изображение:

// 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); 
+0

Благодарим за помощь! Я пробовал ваше решение, которое отлично работает - значит, я могу кодировать и декодировать снова, чтобы установить изображение в imageView. Из моего понимания я должен быть в состоянии сделать ByteArrayInputStream бис = новый ByteArrayInputStream (imageBytes); BufferedImage image = ImageIO.read (bis); но изображение - null. Какая недостающая часть получит BufferedImage? – tonimaroni

+0

Я спрашиваю об этом, потому что я думаю, что кодировка Base64 ошибочна ... я отправил String на свой веб-сервер и расшифровал его там, но не смотрел. Поэтому я попытался получить BufferedImage прямо на gluon-mobile, как указано выше, но его значение null (как в веб-сервисе). Значит, он не может понять данные, которые он получает. Надеюсь на это намек и больше просветления. Благодарю. – tonimaroni

+0

Я отредактировал свой ответ с новым решением, которое позволит вам создать bufferedImage. Дайте мне знать, если это сработает для вас. –

 Смежные вопросы

  • Нет связанных вопросов^_^