Details
-
Improvement
-
Status: Resolved
-
Minor
-
Resolution: Fixed
-
2.0
-
None
Description
The current GrayscaleDecorator doesn't work properly when the decorated component uses transparency – it turns the transparent pixels black, which seems unlikely to be what you want. Here's a new version of GrayscaleDecorator#prepare that creates the BufferedImage in a transparency-aware way:
public Graphics2D prepare(Component component, Graphics2D graphics) {
this.graphics = graphics;
int width = component.getWidth();
int height = component.getHeight();
// To convert to gray, we create a BufferedImage in the grayscale color space
// into which the decorated component draws, and we output the resulting image.
// The naive way to create the buffer is
// new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
// but that doesn't respect transparency. Hence the following more complicated method.
if (bufferedImage == null
bufferedImage.getWidth() < width |
---|
bufferedImage.getHeight() < height) { ColorSpace gsColorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY); ComponentColorModel ccm = new ComponentColorModel(gsColorSpace, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); WritableRaster raster = ccm.createCompatibleWritableRaster(width, height); bufferedImage = new BufferedImage(ccm, raster, ccm.isAlphaPremultiplied(), null); } |
bufferedImageGraphics = bufferedImage.createGraphics();
bufferedImageGraphics.setClip(graphics.getClip());
return bufferedImageGraphics;
}