我需要将BufferedImage
s(RGB,无伪影)转换为字节数组进行发送.在进行单元测试时,我偶然发现了一个问题,无论是BufferedImage
我的期望还是我的代码.
甲BufferedImage
转换再次相同的字节数组后转换为字节阵列和回收率.我认为它是相同的图像.但是,如果我将原始图像和看似相同的背面转换图像转换为灰度图像,这会给我完全不同的图像(不仅仅是一个字节,真的不同!).显然,我希望灰度图像是相同的,因为源是相同的.任何人都可以开导我吗?我有点不对劲吗?
我有一个完整的剥离示例.
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!!!!"); } } }
谢谢你的帮助.