edit: What we have established so far:
- The images (both before and after) are TYPE_BYTE_INDEXED (13) with IndexColorModel (color map)
- The before image has a transparent color in the color map, at index 255 (which is the value -1 in the byte array, as Java uses signed
byte
s). The after image has a different value at this index, that is not transparent. - The images are serialized/deserialized in PNG format, using ImageIO
- The images are visually equal, but the raw pixel data (the byte array) differs
Which leads to the conclusion that the ImageIO PNGImageWriter re-arranges the entries in the color map when writing, resulting in different pixel data/color map.
This basically leaves us with two options:
Serialize the image data in a different way, to assure the color map/pixel data is not modified. It is possible to send the pixel data array, along with the color map array and the height/width of the image, and then re-create the image exactly at the client. This is quite a bit of code, and is probably covered by other questions on SO.
Don't rely on the pixel data/color maps being the same. Use the value of
((IndexColorModel) levelBufferedNew.getColorModel()).getTransparentPixel()
to test for/set transparency instead of the hardcoded value-1
. This requires pretty much no other change in your code.
Note: These solutions will only work for TYPE_BYTE_INDEXED (13) images.
For a more generic (but possibly slower) approach, use the code in the original answer to set transparent parts, and use (levelBufferedNew.getRGB(x, y) >> 24) == 0
to test for transparency. This should work even for TYPE_INT_ARGB or TYPE_4BYTE_ABGR.
original answer:
Instead of fiddling with the image at byte array level, why not try using normal Java2D? ;-)
Something like:
Graphics2D g = levelBufferedNew.createGraphics();
try {
g.setComposite(AlphaComposite.Clear);
g.fillOval(x, y, w, h); // The area you want to make transparent
}
finally {
g.dispose();
}
...should work.
PS: As the images use IndexColorModel
, you can use the getTransparentPixel()
to get the transparent pixel index, instead of relying on it being at a certain index (-1/255). Then you can still manipulate at byte array level. ;-)