Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8039794

BufferedImage broken starting with 1.7.0_25

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P3 P3
    • 9
    • 7u25, 8, 9
    • client-libs
    • 2d
    • x86_64
    • linux

      FULL PRODUCT VERSION :
      java version "1.7.0_25"
      OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.13.04.2)
      OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux pc24-2 3.8.0-35-generic #50-Ubuntu SMP Tue Dec 3 01:24:59 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      I need to convert BufferedImages (RGB, no artefacts) and convert them to byte arrays for sending. While unit testing I stumbled over a problem with either BufferedImage, my expectation, or my code.

      A BufferedImage converted to a byte array and back yields after conversion again the same byte array. It assume it is the same image. However, if I convert both the original and the seemingly identical back-converted image to grey scale this gives me totally different images (not just a byte, really different!). Obviously, I except the grey scale images to be identical as the source is identical. Can anybody enlighten me? Do I expect something wrong?

      I have a complete stripped down example, which complains accordingly.

      See code or

      http://stackoverflow.com/questions/21361109/bufferedimage-same-image-after-conversion-to-byte-array-and-back-but-different



      REGRESSION. Last worked in version 6u43

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.6.0_27"
      OpenJDK Runtime Environment (IcedTea6 1.12.6) (6b27-1.12.6-1~deb7u1)
      OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the provided test case

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I do not want to read:
         AAAAAAaaaaaaaaaaahhhhhhhhhhhh
         Why they have different grey images!!!!

      ACTUAL -
      I have to read:
         AAAAAAaaaaaaaaaaahhhhhhhhhhhh
         Why they have different grey images!!!!


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BasicStroke;
      import java.awt.Graphics2D;
      import java.awt.Rectangle;
      import java.awt.color.ColorSpace;
      import java.awt.image.BufferedImage;
      import java.awt.image.BufferedImageOp;
      import java.awt.image.ColorConvertOp;
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.Random;

      import javax.imageio.ImageIO;


      public class GreyImageProblem {
          private static Random random = new Random();
          private static int randInt(int from, int to) {
              return random.nextInt(to-from+1)+from;
          }
          private static java.awt.Color randColor() {
              return new java.awt.Color(randInt(0,256*256*256));
          }

          // a random image with different RGB colors
          public static BufferedImage genImage() {
              int width = randInt(180, 640);
              int height = randInt(120, 480);
              BufferedImage im = new BufferedImage(width, height,
                  BufferedImage.TYPE_INT_RGB);
              Graphics2D graphics = im.createGraphics();
              graphics.setStroke(new BasicStroke(6));
              Rectangle rectangle = new Rectangle(0, 0, width, height);
              for (int i=0; i < 42; i+=1) {
                  int x = randInt(0, width), y = randInt(0, height);
                  int sw = randInt(0, width)/10, sh = randInt(0, height)/10;
                  graphics.setColor(randColor());
                  rectangle.setBounds(x, y, sw, sh);
                  graphics.draw(rectangle);
              }
              return im;
          }

          // make it grey
          public static BufferedImage toGrey(BufferedImage im) {
              ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
              BufferedImageOp op = new ColorConvertOp(cs, null);
              return op.filter(im, null);
          }

          // make it byte array
          public static byte[] toByteArray(BufferedImage im) {
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              try {
                  ImageIO.write(im, "png", baos);
                  baos.flush();
                  byte[] ret = baos.toByteArray();
                  baos.close();
                  return ret;
              } catch (IOException e) {
                  throw new RuntimeException(e);
              }
          }

          // make it an image again
          public static BufferedImage fromByteArray(byte[] ba) {
              InputStream in = new ByteArrayInputStream(ba);
              try {
                  BufferedImage im = ImageIO.read(in);
                  return im;
              } catch (IOException e) {
                  throw new RuntimeException(e);
              }
          }

          public static boolean sameByteArray(byte[] a, byte[] b) {
              if (a.length != b.length) {
                  System.out.format("sameByteArray: a.length=%d, b.length=%d\n",
                             a.length, b.length);
                  return false;
              }
              for (int i=0; i < a.length; i++) {
                  if (a[i] != b[i]) {
                      return false;
                  }
              }
              return true;
          }

          public static void main(String[] args) {
              BufferedImage image = genImage();
              byte[] imagebytes = toByteArray(image);
              BufferedImage imageAgain = fromByteArray(imagebytes);
              BufferedImage imageGrey = toGrey(image);
              BufferedImage imageAgainGrey = toGrey(imageAgain);
              if (sameByteArray(imagebytes, toByteArray(imageAgain))) {
                  System.out.println("Both are the same images");
              }
              if (!sameByteArray(toByteArray(imageGrey), toByteArray(imageAgainGrey))) {
                  System.out.println("AAAAAAaaaaaaaaaaahhhhhhhhhhhh");
                  System.out.println("Why they have different grey images!!!!");
              }
          }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      not use BufferedImage or not use serialized form.

            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: