在将图像转换为字节数组时使用JProgressBar

时间:2014-07-18 00:08:23

标签: java swing jprogressbar

以下是将图像转换为字节数组的简单代码(已在本论坛中显示):

File imgPath= new File(textFiled_Path.getText());
BufferedImage originalImage = ImageIO.read(imgPath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "png", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray(); 

但是,当图像尺寸很大时,程序会花费太多时间进行转换。因此,我正在考虑在GUI中添加一个JProgressBar,让用户知道剩下多少时间。我见过的所有例子主要是处理带有循环的JProgressBar。我不知道如何从这里开始:(我可以有一个想法开始。换句话说,我应该把JProgressBar放在哪里。

提前谢谢你。

1 个答案:

答案 0 :(得分:2)

所以,你需要两件事......

首先,你需要一些方法来监控图像加载和写入的进度......这很快就会变得有点复杂,因为能够监视操作的进度,你需要知道实际的ImageIO使用的读者/作者....

File file = new File("...");
try (ImageInputStream iis = ImageIO.createImageInputStream(file)) {
    Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
    if (readers.hasNext()) {
        ImageReader reader = readers.next();
        reader.addIIOReadProgressListener(new IIOReadProgressListener() {
            @Override
            public void sequenceStarted(ImageReader source, int minIndex) {
            }

            @Override
            public void sequenceComplete(ImageReader source) {
            }

            @Override
            public void imageStarted(ImageReader source, int imageIndex) {
            }

            @Override
            public void imageProgress(ImageReader source, float percentageDone) {
                //TODO: Update progress...
            }

            @Override
            public void imageComplete(ImageReader source) {
            }

            @Override
            public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) {
            }

            @Override
            public void thumbnailProgress(ImageReader source, float percentageDone) {
            }

            @Override
            public void thumbnailComplete(ImageReader source) {
            }

            @Override
            public void readAborted(ImageReader source) {
            }
        });
        reader.setInput(iis);
        try {
            BufferedImage img = reader.read(0);

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
                Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("png");
                if (writers.hasNext()) {
                    ImageWriter writer = writers.next();
                    writer.addIIOWriteProgressListener(new IIOWriteProgressListener() {
                        @Override
                        public void imageStarted(ImageWriter source, int imageIndex) {
                        }

                        @Override
                        public void imageProgress(ImageWriter source, float percentageDone) {
                            // TODO: Update progress
                        }

                        @Override
                        public void imageComplete(ImageWriter source) {
                        }

                        @Override
                        public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
                        }

                        @Override
                        public void thumbnailProgress(ImageWriter source, float percentageDone) {
                        }

                        @Override
                        public void thumbnailComplete(ImageWriter source) {
                        }

                        @Override
                        public void writeAborted(ImageWriter source) {
                        }
                    });

                    writer.setOutput(ios);
                    try {
                        writer.write(img);
                    } finally {
                        writer.removeAllIIOWriteProgressListeners();
                    }
                }
            }
        } finally {
            reader.removeAllIIOReadProgressListeners();
        }
    }
} catch (IOException exp) {
    exp.printStackTrace();
}

好的,现在你有了,你需要的下一件事是在事件调度线程的上下文之外执行它,以便不阻止UI,所以UI将保持响应,但你也想要一种可以轻松更新UI而不违反单线程规则的方法(UI的更新必须在事件调度线程的上下文中完成)

为此,SwingWorker非常适合。

基本上,您可以使用doInBackground方法来读取/写入图像,可以使用进度属性支持更新进度指示器,并且可以使用publish / process方法提供有关当前操作的其他信息。

您甚至可以使用done方法来处理在doInBackground方法完成后需要更新UI的情况。

example