我有一个方法可以保存图像并在保存时显示其进度。总体而言,该方法似乎有效,但如果我多次调用它有时会给我一个IllegalArgumentException错误。
这是堆栈跟踪:
java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.getImageReaders(ImageIO.java:641)
at com.forseth11.ColorEncoder.Encoder.saveImage(Encoder.java:308)
at com.forseth11.ColorEncoder.Encoder.encode(Encoder.java:82)
at com.forseth11.ColorEncoder.Encoder$3.run(Encoder.java:376)
at java.lang.Thread.run(Thread.java:745)
我不知道为什么会出现此错误或如何解决此问题。我需要能够多次调用此方法来连续保存多个图像。
以下是方法:
private void saveImage(final BufferedImage image, final String string, final File outputfile) throws IOException, InterruptedException {
Thread thread = new Thread(new Runnable(){
public void run() {
try {
ImageIO.write(image, string, outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
ImageInputStream iis = ImageIO.createImageInputStream(outputfile);
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
if (readers.hasNext()) {
ImageReader reader = readers.next();
reader.setInput(iis);
try {
BufferedImage img = reader.read(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();//This is the line the error is pointing to.
try {
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("png");
if (writers.hasNext()) {
ImageWriter writer = writers.next();
writer.addIIOWriteProgressListener(new IIOWriteProgressListener() {
public void imageStarted(ImageWriter source, int imageIndex) {
}
public void imageProgress(ImageWriter source, float percentageDone) {
System.out.println("UPDATE: " + percentageDone);//TODO
}
public void imageComplete(ImageWriter source) {
}
public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
}
public void thumbnailProgress(ImageWriter source, float percentageDone) {
}
public void thumbnailComplete(ImageWriter source) {
}
public void writeAborted(ImageWriter source) {
}
});
writer.setOutput(ios);
try {
writer.write(img);
} finally {
writer.removeAllIIOWriteProgressListeners();
}
}
} finally {
reader.removeAllIIOReadProgressListeners();
}
} finally {
reader.removeAllIIOReadProgressListeners();
}
}
} catch (IOException exp) {
exp.printStackTrace();
}
thread.join();//I added this so it will not leave the method until the image is saved.
}
我获得了从here获取图像保存百分比的代码。我修改了一下。
如何使用此方法保存图像并打印保存的百分比而不会出现错误?另外,为什么在连续两次调用方法时并不总是给我一个错误?
答案 0 :(得分:2)
不要使用以下线程
Thread thread = new Thread(new Runnable(){
public void run() {
try {
ImageIO.write(image, string, outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
因为当outputfile没有准备就绪时,你继续使用以下代码
ImageInputStream iis = ImageIO.createImageInputStream(outputfile);
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
答案 1 :(得分:0)
错误是这些行的结果,每个堆栈跟踪,所以你的:
ImageInputStream iis = ImageIO.createImageInputStream(outputfile);
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
我用google搜索了ImageIO源代码并在此处找到了它: this issue
抛出异常的源代码片段是:
public static Iterator<ImageReader> More ...getImageReaders(Object input) {
640 if (input == null) {
641 throw new IllegalArgumentException("input == null!");
642 }
643 Iterator iter;
644 // Ensure category is present
645 try {
646 iter = theRegistry.getServiceProviders(ImageReaderSpi.class,
647 new CanDecodeInputFilter(input),
648 true);
649 } catch (IllegalArgumentException e) {
650 return Collections.emptyIterator();
651 }
652
653 return new ImageReaderIterator(iter);
654 }
“ImageIO.createImageInputStream(outputfile)”方法调用中有多种情况可能导致问题,基于查看源:服务提供者对注册表的调用是抛出异常,还是返回的服务提供者迭代器没有成员。在这两种情况下,都会得到null返回。
我建议下载jar代码本地并在此源代码中设置条件断点,以便您可以确切地看到发生了哪种情况。
希望有助于找到问题的根源。
答案 2 :(得分:0)
事实证明我不理解我正在使用的代码。显然,当我只想写自己的时候,它正试图读取文件。
这是我的新方法,似乎可以解决任何人遇到类似问题的方法:
private void saveImage(final BufferedImage image, final String string, final File outputfile) throws IOException, InterruptedException {
Thread thread = new Thread(new Runnable(){
public void run() {
try {
ImageIO.write(image, string, outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(string);
if (writers.hasNext()) {
ImageWriter writer = writers.next();
writer.addIIOWriteProgressListener(new IIOWriteProgressListener() {
public void imageStarted(ImageWriter source, int imageIndex) {
}
public void imageProgress(ImageWriter source, float percentageDone) {
System.out.println("UPDATE: " + percentageDone);//TODO
}
public void imageComplete(ImageWriter source) {
}
public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
}
public void thumbnailProgress(ImageWriter source, float percentageDone) {
}
public void thumbnailComplete(ImageWriter source) {
}
public void writeAborted(ImageWriter source) {
}
});
writer.setOutput(ios);
try {
writer.write(image);
} finally {
writer.removeAllIIOWriteProgressListeners();
}
}
thread.join();
}