-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
7u25, 8, 9
-
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.
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.