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