Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6687970
Votes 8
Synopsis Saving image using ImageIO along with metadata makes the image red
Category java:imageio
Reported Against
Release Fixed
State 3-Accepted, bug
Priority: 4-Low
Related Bugs
Submit Date 14-APR-2008
Description
FULL PRODUCT VERSION :
1.6.0_05-b13

ADDITIONAL OS VERSION INFORMATION :
Windows XP Professional 5.1.2600 Service Pack 2 Build 2600

EXTRA RELEVANT SYSTEM CONFIGURATION :
AMD Athlon 64 2Ghz 3800x2
ATI X300SE 128MB VRAM video card
2GB of RAM

A DESCRIPTION OF THE PROBLEM :
In my image resize/compress code I'm trying to save an image along with its Exif metadata but for some images the image becomes red. I'm using com.sun.imageio.plugins.jpeg.JPEGImageReader and com.sun.imageio.plugins.jpeg.JPEGImageWriter. The image type is TYPE_3BYTE_BGR



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Load the image as in the code provided
2. Save it
3. You will see the result by looking at the image

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I was expecting the image to look the same not to look red.
ACTUAL -
The image is scaled but it's red.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

 
 
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Locale;
 
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
 
public class Thumbnail {
    int thumbWidth, thumbHeight;
    private final static boolean debug = true;
    private BufferedImage thumbImage;
    public Thumbnail(String inFile,String outFile,int thumbWidth,int thumbHeight,int quality){
        this.thumbHeight = thumbHeight;
        this.thumbWidth = thumbWidth;
        BufferedImage image = null;
        ImageIO.setUseCache(false);
 
        File srcImageFile = new File(inFile);
        ImageInputStream iis = null;
        IIOImage srcIIOImage = null ;
        ImageReader reader =null;
        try {
 
            iis = ImageIO.createImageInputStream(srcImageFile);
            reader = (ImageReader) ImageIO.getImageReaders(iis).next();
            System.out.println(reader.getClass().getName());
            reader.setInput(iis);
            srcIIOImage = reader.readAll(0, null);
 
        } catch (IOException iioex) {
            if(iioex.getMessage() != null &&
                    iioex.getMessage().endsWith("without prior JFIF!")
            ){
                System.err.println("Trying workaround for java bug");
                System.err.println("http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4924909");
                System.err.println("Please vote for this bug!");
                try {
                    iis.close();
                    iis = patch(srcImageFile);
                    reader.setInput(iis);
                    srcIIOImage = reader.readAll(0, null);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
 
            }
        }finally{
            if(iis !=null){
                try {
                    iis.flush();
                    iis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
 
            }
        }
        image = (BufferedImage)srcIIOImage.getRenderedImage();

        double thumbRatio = (double)thumbWidth / (double)thumbHeight;
        int imageWidth = srcIIOImage.getRenderedImage().getWidth();
        int imageHeight = srcIIOImage.getRenderedImage().getHeight();
        if(debug){
            System.out.println(imageWidth + ": " + srcIIOImage.getRenderedImage().getWidth());
            System.out.println(imageHeight + ": " + srcIIOImage.getRenderedImage().getHeight());
            System.out.println( image.getType());
        }
        double imageRatio = (double)imageWidth / (double)imageHeight;
        if (thumbRatio < imageRatio) {
            thumbHeight = (int)(thumbWidth / imageRatio);
        } else {
            thumbWidth = (int)(thumbHeight * imageRatio);
        }
        thumbImage = new BufferedImage(thumbWidth, thumbHeight, image.getType());

        Graphics2D graphics2D = thumbImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
        graphics2D.dispose();
 
        IIOMetadata metadata =  srcIIOImage.getMetadata();
        IIOImage destIIOImage = new IIOImage(thumbImage, null,metadata);
 
        // save thumbnail image to OUTFILE
        BufferedOutputStream out;
        ImageWriter writer = null;
        ImageOutputStream imgout = null;
        FileOutputStream fos =null;
        try {
            fos = new FileOutputStream(outFile);
            out = new BufferedOutputStream(fos);
            //      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //   JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);
            quality = Math.max(0, Math.min(quality, 100));
            Iterator it = null;
            if(inFile.toUpperCase().endsWith(".JPG") || inFile.toUpperCase().endsWith(".JPEG")){
                it = ImageIO.getImageWriters(new ImageTypeSpecifier((BufferedImage)image), "jpg");
                if(it.hasNext()){
                    imgout = ImageIO.createImageOutputStream(out);
                    writer = (ImageWriter) it.next();
                    System.out.println(writer.getClass().getName());
                    writer.setOutput(imgout);
                    ImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault());
                   // ImageWriteParam param = writer.getDefaultWriteParam();
                    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                    param.setCompressionQuality(quality/100f);
                    IIOMetadata meta = writer.getDefaultStreamMetadata(param);
                    writer.write(meta, destIIOImage, param);
                    image = null;
                }
            } else if(inFile.toUpperCase().endsWith(".BMP")){
                it = ImageIO.getImageWriters(new ImageTypeSpecifier((BufferedImage)image), "bmp");
                if(it.hasNext()){
                    // Save the scaled version out to the file
                    imgout = ImageIO.createImageOutputStream(out);
                  
                    writer = (ImageWriter) it.next();
                    ImageWriteParam iwp = writer.getDefaultWriteParam();
                    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                    iwp.setCompressionType("BI_RGB");
                    writer.setOutput(imgout);
 
                    writer.write(null, new IIOImage(thumbImage, null, null), iwp);
                    image = null;
                }
            }
        } catch (FileNotFoundException e2) {
            e2.printStackTrace();
        }  catch (IOException e) {
            e.printStackTrace();
        } catch(Throwable e){
            e.printStackTrace();
        }
        finally{
            if(fos != null){
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(writer != null)
                writer.dispose();
            try {
                if(imgout != null){
                    imgout.flush();
                    imgout.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    /** Patches a JPEG file that is missing a JFIF marker **/
    private static class PatchInputStream extends FilterInputStream{
        private static final int[] JFIF = {0xFF,
            0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49,
            0x46, 0x00, 0x01, 0x02, 0x00, 0x00,
            0x01, 0x00, 0x01, 0x00, 0x00};
        int position = 0;
 
        public PatchInputStream(InputStream in){
            super(in);
        }
 
        public int read() throws IOException{
            int result;
            if(position < 2){
                result = in.read();
            } else if (position < 2 + JFIF.length){
                result = JFIF[position - 2];
            } else {
                result = in.read();
            }
            position++;
            return result;
        }
 
        public int read(byte[] b, int off, int len)
        throws IOException{
            final int max = off + len;
            int bytesread = 0;
            for(int i=off; i<max; i++){
                final int bi = read();
                if(bi == -1){
                    if(bytesread == 0){
                        bytesread = -1;
                    }
                    break;
                } else {
                    b[i] = (byte) bi;
                    bytesread ++;
                }
            }
            return bytesread;
        }
 
    }
 
    private static ImageInputStream patch(File jpeg) throws IOException{
        InputStream in = new FileInputStream(jpeg);
        in = new BufferedInputStream(in);
        in = new PatchInputStream(in);
        return ImageIO.createImageInputStream(in);
    }
    public int getHeight(){
        return thumbHeight;
    }
    public int getWidth(){
        return thumbWidth;
    }
 
    public int getPropertion(){
        return thumbWidth/thumbHeight;
    }
    /**
     * @return the thumbImage
     */
    public BufferedImage getThumbImage() {
        return thumbImage;
    }
}
---------- END SOURCE ----------
Posted Date : 2008-04-14 08:36:29.0
Work Around
N/A
Evaluation
N/A
Comments
  
  Include a link with my name & email   

Submitted On 06-JUN-2008
Hi, I'm developping an upload applet, available here:
http://sourceforge.net/projects/jupload/

Users complains about problems when uploading pictures with metadata. It's this bug.

It is impossible, for instance, to manage properly pictures from EOS 30D et 40D with metadata. It occurs with other camera of other brands, but I have no list to give. It may be due to new metadaformat (EXIF 2.21?).

Here is a link to another sample (this picture becomes green...):
http://etiennegauthier.free.fr/metadataCase.jar


Submitted On 18-NOV-2009
joadams
I have come across this bug many times and would very much appreciate a prompt bug fix.



PLEASE NOTE: JDK6 is formerly known as Project Mustang