用红色掩码创建的Java缓冲图像

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

这张图片是以红色调写的。是否需要设置某些选项才能正确读取此图像?


2
请查看使用ImageIO在Java中处理奇怪颜色的JPEG图像。我听说过这个问题几次,但从未遇到过,我使用PNG。 - MadProgrammer
6个回答

5
问题可能与 ImageIO.read 相关,它无法正确读取某些JPG图像。这里有一个类似的 bug (Bug 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();
        }
    }
}

这是结果: enter image description here

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

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 第三个参数中的颜色空间。

0

这里是一个Java Servlet示例,可以绕过使用imageIO的问题:

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

0
BufferedImage bi =
   ImageIO.read(
      "http://tctechcrunch2011.files.wordpress.com/2012/10/gmm.jpg" );
ImageIO.write( bi, 'JPEG', new File( "badimage.jpeg" );

0

如其他答案所述,这是一个已知的 bug,存在于 ImageIO 和 Oracle JRE 捆绑的标准 JPEG 插件中。

然而,通过使用 TwelveMonkeys ImageIO JPEG 插件 来替换 JPEG 插件,可以继续像 OP 原始代码中那样使用 ImageIO。您只需要将 JAR 文件及其依赖项添加到运行时类路径中即可,不需要进行任何代码更改 (我已经使用了 OP 的测试文件进行了测试)。

该插件特别设计用于解决标准 JPEG 插件中的许多问题或缺陷。它支持 CMYK JPEG、损坏的 ICC 配置文件、Exif 数据等。该插件由我开发,并在开源 BSD 许可证下免费分发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接