在 Gluon Mobile 中访问图像文件夹
Accessing Folder of Images in 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);
}
在目录结构中还有什么我需要考虑的吗?
如果您 运行 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
。
这对我有用,前提是您在 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.
我知道为了获得名称已知的单个图像,我可以使用
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);
}
在目录结构中还有什么我需要考虑的吗?
如果您 运行 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
。
这对我有用,前提是您在 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.