java buffered image created with red mask

天大地大妈咪最大 提交于 2019-11-26 18:35:30

问题


I am having trouble reading an image. If I do the following

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

the image is written with a red tint. Is there some option that needs to be set to read this image correctly?


回答1:


The problem maybe related to ImageIO.read that fails to correctly read some JPG images. Here is a similar bug (Bug ID: 4881314) that may still be partially unresolved.

As an alternative you can try using Toolkit.createImage that seems to handle the specified image correctly. For example:

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

Here is the result:




回答2:


Sorry. I don't have the answer to why there is a red tint.

This is how we read images in our software. In our case we are using the scalar library to resize the image.

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



回答3:


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



回答4:


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

The code above DOES NOT use Image.read which (quite probably) contains a bug. It doesn't produce red images. But I'm not sure about colorspace in BufferedImage third parameter.




回答5:


As mentioned in other answers, this is a known bug in the standard JPEG plugin that comes bundled with ImageIO and the Oracle JRE.

However, it's possible to continue to use ImageIO as in the OP's original code, by replacing the JPEG plugin with the TwelveMonkeys ImageIO JPEG plugin. You only need to add the JAR and its dependencies to the runtime classpath. No code changes necessary (I tested with the OP's test files).

The plugin is especially made to work around or fix the many issues with the standard JPEG plugin. It supports CMYK JPEGs, broken ICC profiles, Exif data and more. The plugin is developed by me, and is freely distributable under the open source BSD license.




回答6:


Here is a Java Servlet Example for a Workaround whitout using 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();
}


来源:https://stackoverflow.com/questions/12963685/java-buffered-image-created-with-red-mask

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!