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

时间:2012-10-18 20:59:47

标签: java awt java-2d

我无法阅读图片。如果我做以下

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

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

6 个答案:

答案 0 :(得分:5)

问题可能与ImageIO.read无法正确读取某些JPG图像有关。这是一个类似的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 :(得分: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);

答案 2 :(得分:0)

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

答案 3 :(得分: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(很可能)包含一个bug。它不会产生红色图像。但我不确定BufferedImage第三个参数中的色彩空间。

答案 4 :(得分:0)

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

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

该插件特别适用于解决标准JPEG插件的许多问题。它支持CMYK JPEG,破坏的ICC配置文件,Exif数据等。该插件由我开发,可以在开源BSD许可下自由分发。

答案 5 :(得分:0)

以下是使用imageIO的变通方法whitout的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();
}