Reference Information. I need to be able to create images in a "disconnected" form. Usually the proposed approach is to convert images to shades of gray and show the image in gradations. The disadvantage is that it only works with images, which makes it cumbersome to show graphics where you do not have direct access to the image in the off state. Now I thought that this can be done on the fly with java.awt.Composite (and then I would not need to know how, for example, the icon is implemented to disable it). Only, it seems there is no implementation for converting to grayscale, so I had to create my own ...
However, I have cracked the implementation (and this does what I expect). But I'm not sure that it will actually work correctly for all cases (Javadocs of Composite / CompositeContext seems extremely thin for such a complex operation). And, as you can see from my implementation, I use a roundabout way of processing pixels by pixels, because there seems to be no easy way to read / write pixels in bulk in a format not dictated by the related rasters.
Any pointers to more extensive documentation / examples / tips are appreciated.
Here's SSCCE - it displays the (color) GradientPaint through DisabledComposite to convert the gradient to grayscale. Please note that in the real world you will not know what is displayed using calls. A gradient is just an example (sorry, but too often people donβt understand this, so this time I will make it explicit).
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Composite; import java.awt.CompositeContext; import java.awt.Dimension; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class CompositeSSCE implements Runnable { static class DisabledComposite implements Composite { @Override public CompositeContext createContext( final ColorModel srcColorModel, final ColorModel dstColorModel, final RenderingHints hints) { return new DisabledCompositeContext(srcColorModel, dstColorModel); } } static class DisabledCompositeContext implements CompositeContext { private final ColorModel srcCM; private final ColorModel dstCM; final static int PRECBITS = 22; final static int WEIGHT_R = (int) ((1 << PRECBITS) * 0.299); final static int WEIGHT_G = (int) ((1 << PRECBITS) * 0.578); final static int WEIGHT_B = (int) ((1 << PRECBITS) * 0.114); final static int SRCALPHA = (int) ((1 << PRECBITS) * 0.667); DisabledCompositeContext(final ColorModel srcCM, final ColorModel dstCM) { this.srcCM = srcCM; this.dstCM = dstCM; } public void compose(final Raster src, final Raster dstIn, final WritableRaster dstOut) { final int w = Math.min(src.getWidth(), dstIn.getWidth()); final int h = Math.min(src.getHeight(), dstIn.getHeight()); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { int rgb1 = srcCM.getRGB(src.getDataElements(x, y, null)); int a1 = ((rgb1 >>> 24) * SRCALPHA) >> PRECBITS; int gray = ( ((rgb1 >> 16) & 0xFF) * WEIGHT_R + ((rgb1 >> 8) & 0xFF) * WEIGHT_G + ((rgb1 ) & 0xFF) * WEIGHT_B ) >> PRECBITS; int rgb2 = dstCM.getRGB(dstIn.getDataElements(x, y, null)); int a2 = rgb2 >>> 24; int r2 = (rgb2 >> 16) & 0xFF; int g2 = (rgb2 >> 8) & 0xFF; int b2 = (rgb2 ) & 0xFF;
Durandal
source share