6

When I try to compress the a jpg image, most of the time it work perfectly, however some jpg image turn green after the compression. Here is my code

public void compressImage(String filename, String fileExtension) {
    BufferedImage img = null;
    try {
        File file = new File(filename);
        img = ImageIO.read(file);

        if (fileExtension.toLowerCase().equals(".png") || fileExtension.toLowerCase().equals(".gif")) {
            //Since there might be transparent pixel, if I dont do this,
            //the image will be all black.
            for (int x = 0; x < img.getWidth(); x++) {
                for (int y = 0; y < img.getHeight(); y++) {
                    int rgb = img.getRGB(x, y);
                    int alpha = (rgb >> 24) & 0xff;
                    if (alpha != 255) {
                        img.setRGB(x, y, -1); //set white
                    }
                }
            }
        }
        Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
        //Then, choose the first image writer available
        ImageWriter writer = (ImageWriter) iter.next();
        //instantiate an ImageWriteParam object with default compression options
        ImageWriteParam iwp = writer.getDefaultWriteParam();
        //Set the compression quality
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(0.8f);
        //delete the file. If I dont the file size will stay the same
        file.delete();
        ImageOutputStream output = ImageIO.createImageOutputStream(new File(filename));
        writer.setOutput(output);
        IIOImage image = new IIOImage(img, null, null);
        writer.write(null, image, iwp);
        writer.dispose();
    } catch (IOException ioe) {
        logger.log(Level.SEVERE, ioe.getMessage());
    }
}

Original Image Compress Image. Image turn green

Thang Pham
  • 38,125
  • 75
  • 201
  • 285
  • Out of curiosity, why are you passing a `ServletContext` to this method? It's never used. – Matt Ball Mar 15 '11 at 19:05
  • @Matt: Good point, it was from my old code. I pass in `ServletContext` trying to figure out the `file path`, but then I decide to pass in the `file path` instead – Thang Pham Mar 15 '11 at 19:10
  • 1
    I just ran the code on the test image (the top one) and it did not affect the coloring. [Here's the result](http://i.imgur.com/zwxWb.jpg). It's definitely been compressed (246 KB vs 453 KB). – Matt Ball Mar 15 '11 at 19:22
  • 1
    BTW, you should declare the iterator generically: `Iterator iter = ImageIO.get...`, then you don't need to cast, you can just write this: `ImageWriter writer = iter.next();` – Matt Ball Mar 15 '11 at 19:28
  • @Matt: When u said, the compress image did not change color, did u run my code, Matt? – Thang Pham Mar 15 '11 at 22:43
  • Yes, I ran your code. JDK 6 u24 on Windows 7 x64. – Matt Ball Mar 16 '11 at 00:36
  • 1
    I also just ran the code on JRE 6 on OS X 10.6 - no issues there either. Could it possibly be [this problem](http://stackoverflow.com/questions/1271658/)? The only difference I could see in the exif tags was that the original image's JFIF version is 1.1, and the processed image's version is 1.2. – Matt Ball Mar 16 '11 at 00:52

3 Answers3

1

Converting the final image from YUV back to RGB, will restore the colors of the image. This conversion worked for me: cv2.cvtColor(img_file, cv2.COLOR_YUV2RGB)

Procrastinator
  • 2,526
  • 30
  • 27
  • 36
0

I have the same problem. In my test server run java 7 oracle and work fine. In my production server run openJDK 1.7, and compress images turn green...It´s seems bug in some JAVA versions.

thiagoms83
  • 81
  • 3
0

From experience, I know that green is the color of freshly formatted YUV memory (YV12, in particular). So my guess is some step is failing, and you get luma information but the chroma gets botched. Looks to me like it's failing before it gets to the Cr plane.

Anyway, good luck, that's a tough one. Your code looks strange though--what's with the weird png specific code at the top? AFAIK, if you're using .NET you can pretty much treat any registered image format just as though it's an image without any funny work.

kidjan
  • 1,471
  • 14
  • 16