在Gluon Mobile中访问图像文件夹

时间:2017-01-09 00:04:10

标签: gluon gluon-mobile

我知道为了获得名称已知的单个图像,我可以使用

getClass().getResource()..

但是,如果我在特定文件夹中有很多图像怎么办?我不想要获取每个图像名称并调用getResource()方法。

以下适用于桌面,但导致Android崩溃

public void initializeImages() {

        String platform = "android";

        if(Platform.isIOS())
        {
            platform = "ios";
        } else if(Platform.isDesktop())
        {
            platform = "main";
        }

        String path = "src/" + platform + "/resources/com/mobileapp/images/";


        File file = new File(path);
        File[] allFiles = file.listFiles();

        for (int i = 0; i < allFiles.length; i++) {
            Image img = null;
            try {
                img = ImageIO.read(allFiles[i]);
                files.add(createImage(img));
            } catch (IOException ex) {
                Logger.getLogger(ImageGroupRetriever.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

 //Taken from a separate SO question. Not causing any issues
 public static javafx.scene.image.Image createImage(java.awt.Image image) throws IOException {
        if (!(image instanceof RenderedImage)) {
            BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),
                    image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
            Graphics g = bufferedImage.createGraphics();
            g.drawImage(image, 0, 0, null);
            g.dispose();

            image = bufferedImage;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write((RenderedImage) image, "png", out);
        out.flush();
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        return new javafx.scene.image.Image(in);
    }

我还需要在目录结构中考虑一些其他内容吗?

1 个答案:

答案 0 :(得分:2)

如果您在Android上运行该代码,则会看到使用adb logcat -v threadtime的异常:

Caused by: java.lang.NullPointerException: Attempt to get length of null array

在你在for循环中调用allFiles.length的行。

在Android上,您无法以与在桌面上相同的方式阅读路径。如果将图像复制到src/android/resources,它就没有什么区别。

如果你检查build / javafxports / android /文件夹,你会找到apk,如果你在IDE上展开它,你会发现图像只是放在com.mobileapp.images下面。

这就是通常getClass().getResource("/com/mobileapp/images/<image.png>")的原因。

您可以做的是将包含所有图像的zip文件添加到已知位置。然后使用Charm Down Storage插件将zip复制到Android上应用程序的私人文件夹,提取图像,最后您将能够通过设备上的专用路径使用File.listFiles

这适用于我,假设您在images.zip下有一个名为com/mobileapp/images的邮政编码,其中包含所有文件:

private List<Image> loadImages() {
    List<Image> list = new ArrayList<>();

    // 1 move zip to storage
    File dir;
    try {
        dir = Services.get(StorageService.class)
                .map(s -> s.getPrivateStorage().get())
                .orElseThrow(() -> new IOException("Error: PrivateStorage not available"));

        copyZip("/com/mobileapp/images/", dir.getAbsolutePath(), "images.zip");
    } catch (IOException ex) {
        System.out.println("IO error " + ex.getMessage());
        return list;
    }

    // 2 unzip
    try {
        unzip(new File(dir, "images.zip"), new File(dir, "images"));
    } catch (IOException ex) {
        System.out.println("IO error " + ex.getMessage());
    }

    // 3. load images
    File images = new File(dir, "images");
    for (int i = 0; i < images.listFiles().length; i++) {
        try {
            list.add(new Image(new FileInputStream(images.listFiles()[i])));
        } catch (FileNotFoundException ex) {
            System.out.println("Error " + ex.getMessage());
        }

    }
    return list;
}

public static void copyZip(String pathIni, String pathEnd, String name)  {
    try (InputStream myInput = BasicView.class.getResourceAsStream(pathIni + name)) {
        String outFileName =  pathEnd + "/" + name;
        try (OutputStream myOutput = new FileOutputStream(outFileName)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.flush();

        } catch (IOException ex) {
            System.out.println("Error " + ex);
        }
    } catch (IOException ex) {
        System.out.println("Error " + ex);
    }
}

public static void unzip(File zipFile, File targetDirectory) throws IOException {
    try (ZipInputStream zis = new ZipInputStream(
            new BufferedInputStream(new FileInputStream(zipFile)))) {
        ZipEntry ze;
        int count;
        byte[] buffer = new byte[8192];
        while ((ze = zis.getNextEntry()) != null) {
            File file = new File(targetDirectory, ze.getName());
            File dir = ze.isDirectory() ? file : file.getParentFile();
            if (!dir.isDirectory() && !dir.mkdirs())
                throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath());
            if (ze.isDirectory())
                continue;
            try (FileOutputStream fout = new FileOutputStream(file)) {
                while ((count = zis.read(buffer)) != -1)
                    fout.write(buffer, 0, count);
            }
        }
    }
}

请注意,这也适用于桌面和iOS。

unzip方法基于此answer