简体   繁体   English

如果多次调用此方法,为什么有时会给我一个错误

[英]Why does this method sometimes give me an error if I call it more than once

I have a method which I am making to save an image and show its progress while saving. 我有一种保存图像并在保存时显示其进度的方法。 Overall the method seems to work, but if I call it more than once it sometimes gives me a IllegalArgumentException error. 总体而言,该方法似乎可行,但如果多次调用它,有时会给我IllegalArgumentException错误。

This is the stack trace: 这是堆栈跟踪:

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)

I don't know why I get this error or how to fix it. 我不知道为什么会收到此错误或如何解决它。 I need to be able to call this method multiple times to save multiple images in a row. 我需要能够多次调用此方法以连续保存多个图像。

Here is the method: 方法如下:

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.
    }

I got the code for getting the percentage the image is saved from here . 我得到了从此处获取图像保存百分比的代码。 I modified it a bit. 我修改了一下。

How can I make this method to save an image and print its percentage saved without getting an error? 如何使该方法保存图像并打印其保存百分比而不出错? Also why does it not always give me an error when I call the method two times in a row? 另外,为什么当我连续两次调用该方法时,它并不总是给我一个错误?

do not use following thread 不要使用以下线程

Thread thread = new Thread(new Runnable(){
    public void run() {
        try {
            ImageIO.write(image, string, outputfile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});
thread.start();

Since when outputfile is not ready you continue with following code 由于当outputfile未准备好时,您将继续以下代码

ImageInputStream iis = ImageIO.createImageInputStream(outputfile);
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);

The error is a result of these lines, per the stack trace, so your: 根据堆栈跟踪,这些行是这些行的结果,因此您:

        ImageInputStream iis = ImageIO.createImageInputStream(outputfile);
        Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);

I googled for the ImageIO source code and found it here: ImageIO source on GrepCode 我在Google上搜索了ImageIO源代码,并在这里找到了它: GrepCode上的ImageIO源代码

The source code snippet throwing the exception is: 引发异常的源代码片段为:

     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     }

There are multiple cases from the "ImageIO.createImageInputStream(outputfile)" method call that can cause issues, based on looking at the source: Either the call to the registry for service providers is throwing an exception, or the returned service providers iterator has no members. 根据查看源,“ ImageIO.createImageInputStream(outputfile)”方法调用中有多种情况会导致问题:根据服务提供者对注册表的调用引发异常,或者返回的服务提供者迭代器没有成员。 In both cases, you get null return. 在这两种情况下,您都将返回null。

I would suggest downloading the jar code local and setting a conditional breakpoint in this source so you can see exactly which case is happening. 我建议在本地下载jar代码并在此源代码中设置条件断点,以便您可以确切地了解正在发生的情况。

Hope that helps get to the source of the issue. 希望这有助于找到问题的根源。

It turns out that I did not understand the code I was using. 事实证明,我不理解所使用的代码。 Apparently it was trying to read a file when I only wanted to write to own. 显然,当我只想写入自己的文件时,它试图读取文件。

Here is my new method which seems to work in case anyone has a similar problem: 这是我的新方法,似乎在任何人遇到类似问题的情况下都可以使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果我输入一个未在数组中定义的值,为什么二进制搜索方法会给我一个错误? - Why does the binary search method give me an error if i put in a value that is not defined in the array? 为什么即使我声明了 rand,它也会给我一个错误? - Why does it give me an error even though I declared rand? 为什么 i = i + i 给我 0? - Why does i = i + i give me 0? 这种方法如何给我一个 -61 错误? - How does this method give me a -61 Error? 为什么我的反向 LinkedList 方法不能多次工作? - Why wont my reverse LinkedList method not work more than once? 为什么 Java 中的“intersectLine”方法给我一个错误的结果? - Why does the "intersectLine" method in Java give me a false result? 为什么它给我一个“预期的方法调用”错误? - Why is it giving me a "method call expected" error? Enum *似乎*被多次初始化,构造函数被多次调用。 如果我是对的,那为什么? - Enum *seems* to be initialized more than once, the constructor is called more than once. If I’m right, then why? 为什么 hibernate 在我放置 transient 标签时会给我这个错误? - Why does hibernate give me this error when I put the transient tag? 如何多次调用 SwingWorker? - How can I call SwingWorker more than once?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM