3

我在阅读图像时遇到问题。如果我执行以下操作

URL url = new URL("http://tctechcrunch2011.files.wordpress.com/2012/10/gmm.jpg");
ImageInputStream stream = ImageIO.createImageInputStream(url.openStream());
ImageReader reader = ImageIO.getImageReaders(stream).next();
reader.setInput(stream, true, true);
BufferedImage image = reader.read(0);

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageWriter writer = ImageIO.getImageWritersByFormatName("JPEG").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
writer.setOutput(ios);
IIOImage ioImage = new IIOImage(image, null, null);
writer.write(ioImage);
ios.close();
FileOutputStream fos = new FileOutputStream("badimage.jpeg");
fos.write(bos.toByteArray());
fos.close();

图像以红色调书写。是否需要设置一些选项才能正确读取此图像?

4

6 回答 6

5

该问题可能与ImageIO.read无法正确读取某些 JPG 图像有关。这是一个类似的错误(错误 ID:4881314),可能仍部分未解决。

作为替代方案,您可以尝试使用Toolkit.createImage似乎可以正确处理指定图像的方法。例如:

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

class TestImage {
    public static void main(String args[]) {
        try {
            URL imageUrl = new URL(
                "http://tctechcrunch2011.files.wordpress.com/2012/10/gmm.jpg");
            BufferedImage ioImage = ImageIO.read(imageUrl);
            Image toolkitImage = Toolkit.getDefaultToolkit().createImage(
                    imageUrl);

            JPanel panel = new JPanel();
            panel.add(new JLabel(new ImageIcon(ioImage)));
            panel.add(new JLabel(new ImageIcon(toolkitImage)));

            JOptionPane.showMessageDialog(null, panel, "ImageIO vs Toolkit",
                    JOptionPane.INFORMATION_MESSAGE);

        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e.getMessage(), "Failure",
                    JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
    }
}

结果如下:

在此处输入图像描述

于 2012-10-19T03:45:28.457 回答
1

对不起。我不知道为什么会有红色调。

这就是我们在软件中读取图像的方式。在我们的例子中,我们使用标量库来调整图像大小。

URL url = new URL("http://tctechcrunch2011.files.wordpress.com/2012/10/gmm.jpg");
BufferedImage source = javax.imageio.ImageIO.read(url);
BufferedImage manipulated = ...
FileOutputStream fos = new FileOutputStream("badimage.jpeg");
javax.imageio.ImageIO.write(manipulated , "png", fos);
于 2012-10-18T21:20:27.860 回答
0
BufferedImage bi =
   ImageIO.read(
      "http://tctechcrunch2011.files.wordpress.com/2012/10/gmm.jpg" );
ImageIO.write( bi, 'JPEG', new File( "badimage.jpeg" );
于 2012-10-18T21:15:02.057 回答
0
ImageIcon mySourceImage = new ImageIcon(sourceImageFile.getAbsolutePath());
BufferedImage sourceImage = new BufferedImage(mySourceImage.getIconWidth(),  mySourceImage.getIconHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g2d2 = (Graphics2D) sourceImage.getGraphics();
mySourceImage.paintIcon(null, g2d2, 0, 0);
g2d2.dispose();

上面的代码不使用 Image.read (很可能)包含错误。它不会产生红色图像。但我不确定 BufferedImage 第三个参数中的颜色空间。

于 2015-04-01T11:06:48.680 回答
0

正如其他答案中提到的,这是与 ImageIO 和 Oracle JRE 捆绑在一起的标准 JPEG 插件中的一个已知错误。

但是,通过将 JPEG 插件替换为TwelveMonkeys ImageIO JPEG 插件,可以继续使用 OP 的原始代码中的ImageIO 。您只需要将 JAR 及其依赖项添加到运行时类路径。无需更改代码(我使用 OP 的测试文件进行了测试)。

该插件专门用于解决或修复标准 JPEG 插件的许多问题。它支持 CMYK JPEG、损坏的 ICC 配置文件、Exif 数据等。该插件由我开发,可在开源 BSD 许可下免费分发。

于 2016-05-19T09:26:55.283 回答
0

这是一个使用 imageIO 的解决方法的 Java Servlet 示例:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{
    //TestImage
    String testImage = "UNC Path or URL.jpg";//Load your image here...

    //Get the streams
    FileInputStream inStream = new FileInputStream(testImage);
    ServletOutputStream outStream = response.getOutputStream();

    //Create the buffers
    BufferedInputStream inBuf = new BufferedInputStream(inStream);
    BufferedOutputStream outBuf = new BufferedOutputStream(outStream);

    //Write input into output
    int ch =0; ;
    while((ch=inBuf.read())!=-1)
        outBuf.write(ch);

    inBuf.close();
    inStream.close();
    outBuf.close();
    outStream.close();
}
于 2017-12-05T13:29:53.877 回答