【问题标题】:Accessing Folder of Images in Gluon Mobile在 Gluon Mobile 中访问图像文件夹
【发布时间】:2017-01-09 00:04:09
【问题描述】:

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

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);
    }

在目录结构中还有什么我需要考虑的吗?

【问题讨论】:

    标签: gluon gluon-mobile


    【解决方案1】:

    如果您在 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/&lt;image.png&gt;") 起作用的原因。

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

    这对我有用,前提是您在 com/mobileapp/images 下有一个名为 images.zip 的 zip,其中包含所有文件:

    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

    【讨论】:

    • 谢谢何塞!我相信我会遇到更多的胶子问题,因为我刚刚开始使用它。我可以看到你是它的专家。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多