I have an 12-bit grayscale
image. I want to display it in Java with BufferedImage
, and I find BufferedImage.TYPE_USHORT_GRAY
is the most suitable. However, it makes my display image almost black (my pixels are in 0 ~ 4095 range).
How can I autoscale it to clearly display it?
Thanks so much.
If your data is stored as 16 bit samples (as indicated in the comments), then you can either:
Multiply the samples (by 16) to the full 16 bit range, and create a BufferedImage.TYPE_USHORT_GRAY
image. Straight forward, but requires massaging and copying the data.
Or, you could also create a custom BufferedImage
with a 12 bit ColorModel
, and just use the data as is. Probably faster, but more verbose/complicated code.
Here's the code to create an image using a 12 bit gray color model:
WritableRaster raster = Raster.createInterleavedRaster(new DataBufferUShort(twelveBitData, twelveBitData.length), w, h, w, 1, new int[]{0}, null);
ColorSpace gray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorModel twelveBitModel = new ComponentColorModel(gray, new int[]{12}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
BufferedImage image = new BufferedImage(twelveBitModel, raster, twelveBitModel.isAlphaPremultiplied(), null);
Full, runnable demo program below.
Alternatively, if your data had been stored as "one and a half byte" packed 12 bit samples, the simplest solution would be to first pad the data to full 16 bit samples.
Demo program:
public class TwelveBit {
public static void main(String[] args) {
int w = 320;
int h = 200;
short[] twelveBitData = new short[w * h];
createRandomData(twelveBitData);
WritableRaster raster = Raster.createInterleavedRaster(new DataBufferUShort(twelveBitData, twelveBitData.length), w, h, w, 1, new int[]{0}, null);
ColorSpace gray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorModel twelveBitModel = new ComponentColorModel(gray, new int[]{12}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
BufferedImage image = new BufferedImage(twelveBitModel, raster, twelveBitModel.isAlphaPremultiplied(), null);
showIt(image);
}
private static void createRandomData(short[] twelveBitData) {
Random random = new Random();
for (int i = 0; i < twelveBitData.length; i++) {
twelveBitData[i] = (short) random.nextInt(1 << 12);
}
}
private static void showIt(final BufferedImage image) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}