此代码尝试在名为“imgs”的目录中调整图像大小。不幸的是,由于某种原因,当我取消注释时,listFiles(..)循环ImageIO.read(sourceImageFile)
将返回null。然而,在循环(res("imgs/foto_3.jpg")
)之外直接处理相同的文件是有效的。显然,这个循环阻止了文件被读取。溶液
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import static org.imgscalr.Scalr.*;
public class App {
public static void main(String[] args) throws IOException {
// for (File sourceImageFile : new File("imgs").listFiles()) {
// res("imgs/"+sourceImageFile.getName());
// }
res("imgs/foto_3.jpg");
}
public static void res(String arg) throws IOException {
File sourceImageFile = new File(arg);
BufferedImage img = ImageIO.read(sourceImageFile);
BufferedImage thumbnail = resize(img, 500);
thumbnail.createGraphics().drawImage(thumbnail, 0, 0, null);
ImageIO.write(thumbnail, "jpg", new File("resized/" + sourceImageFile.getName()));
}
}
要重现问题,您可以download the Maven project。
答案 0 :(得分:2)
您可以更改res
以接受File
对象而不是字符串吗?然后你可以编写以下内容,这样更好:
for (File sourceImageFile : new File("imgs").listFiles()) {
res(sourceImageFile);
}
关于您的原始问题,请尝试添加一些跟踪语句或使用调试器来查找传递给res
的确切内容。
答案 1 :(得分:2)
好的,我明白了。现在它正在运作。 您(或者您在此处创建可下载项目的任何人)正在使用Mac OS,它会自动创建.DS_Store文件。 当您尝试将其传递给res方法时,它不知道如何处理非图像文件并充当null。
public static void main(String[] args) throws IOException {
for (File sourceImageFile : new File("imgs").listFiles()) {
if (sourceImageFile.getName().endsWith(".jpg"))
res(sourceImageFile.getAbsolutePath());
}
}
这是修改后的void main方法。它可以工作,你可以优化if语句,以便更深入地过滤错误的文件。 我还改变了给res方法的参数。它现在看起来更好,因为getAbsoulutePath返回名称和路径。 让我知道它是如何工作的
答案 2 :(得分:2)
我不确定为什么文件列表迭代会混淆缩略图生成,但你私下向我提到你使用的是imgscalr并且很好奇批处理目录的正确代码是什么样的,所以我为你写了这个代码。
下面的代码将处理任何目录(imgs
是硬编码的,以便与您的示例代码保持一致)并将其写入任何其他目录(resized
用于保持一致 - 感觉可以自由更改任一目录)
import static org.imgscalr.Scalr.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ScaleDirExample {
public static void main(String[] args) throws IOException {
File[] images = new File("imgs").listFiles();
for (File f : images) {
System.out.println("Processing: " + f.getName() + "...");
if (f.isDirectory()) {
System.out.println("\tSkipping, file is a directory...");
continue;
} else
process(f);
}
}
private static void process(File file) throws IOException {
// Load image.
BufferedImage image = ImageIO.read(file);
// Resize image.
image = resize(image, 500);
// Save the resized image as the thumbnail.
saveThumbnail(file, image);
}
private static void saveThumbnail(File originalFile, BufferedImage thumbnail)
throws IOException {
String filename = originalFile.getName();
// Determine file extension.
String fileExt = filename.substring(filename.lastIndexOf('.') + 1);
// Save the thumbnail to the resized dir.
ImageIO.write(thumbnail, fileExt, new File("resized/" + filename));
}
}
可以修改对resize(image, 500)
的调用以匹配任何Scalr.resize methods - 您可以根据需要传递过滤器或提高质量。
我的测试设置的示例输出如下:
Processing: flower-dog-gimp.jpg...
Processing: flower-dog.jpg...
Processing: logoOXdaComida.png...
Processing: mr-t-thumbnail.jpg...
Processing: mr-t.jpg...
Processing: problem-trans-peter-griffin.png...
希望有所帮助!
答案 3 :(得分:0)
调试此方法的一种显而易见的方法是输出sourceImageFile
返回null的特定ImageIO.read(..)
。我怀疑它是因为listFiles将为您提供图像目录中所有文件和目录的列表。 listFiles javadoc。您可以通过使用FileFilter来确保listFiles仅返回文件和其他正确类型的文件。
仅返回文件的文件过滤器示例如下:
import java.io.FileFilter
class RegularFilesOnlyFileFilter implements FileFilter {
public boolean accept(File pathName) {
return pathName.isFile();
}
}
使用此过滤器的方法是 - new File("imgs").listFiles(new RegularFilesOnlyFilesFilter())
答案 4 :(得分:-1)
我改变了res方法:
public static void res(File arg) throws IOException {
if (arg.contains(".DS_Store")) {
return;
}
mac-issue(或者应该按照建议过滤非图像文件)!