Java 中的自动缩放范围 16 位灰度图像
Autoscale range 16-bit grayscale image in Java
我有一张 12-bit grayscale
图片。我想用BufferedImage
显示在Java,我觉得BufferedImage.TYPE_USHORT_GRAY
最合适。但是,它使我的显示图像几乎是黑色的(我的像素在 0 ~ 4095 范围内)。
如何自动缩放以清晰显示?
非常感谢。
您需要从 12 位扩展到 16 位。将您的值乘以 16
如果您的数据存储为 16 位样本(如评论中所示),那么您可以:
将样本(乘以 16)乘以完整的 16 位范围,并创建一个 BufferedImage.TYPE_USHORT_GRAY
图像。直截了当,但需要修改和复制数据。
或者,您也可以使用 12 位 ColorModel
创建自定义 BufferedImage
,然后按原样使用数据。可能更快,但更多 verbose/complicated 代码。
下面是使用 12 位灰度颜色模型创建图像的代码:
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);
下面是完整的、可运行的演示程序。
或者,如果您的数据已存储为 "one and a half byte" 打包的 12 位样本,最简单的解决方案是首先将数据填充为完整的 16 位样本。
演示程序:
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);
}
});
}
}
我有一张 12-bit grayscale
图片。我想用BufferedImage
显示在Java,我觉得BufferedImage.TYPE_USHORT_GRAY
最合适。但是,它使我的显示图像几乎是黑色的(我的像素在 0 ~ 4095 范围内)。
如何自动缩放以清晰显示?
非常感谢。
您需要从 12 位扩展到 16 位。将您的值乘以 16
如果您的数据存储为 16 位样本(如评论中所示),那么您可以:
将样本(乘以 16)乘以完整的 16 位范围,并创建一个
BufferedImage.TYPE_USHORT_GRAY
图像。直截了当,但需要修改和复制数据。或者,您也可以使用 12 位
ColorModel
创建自定义BufferedImage
,然后按原样使用数据。可能更快,但更多 verbose/complicated 代码。
下面是使用 12 位灰度颜色模型创建图像的代码:
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);
下面是完整的、可运行的演示程序。
或者,如果您的数据已存储为 "one and a half byte" 打包的 12 位样本,最简单的解决方案是首先将数据填充为完整的 16 位样本。
演示程序:
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);
}
});
}
}