这里的问题是需要setRGB()
一个 0xRRGGBB 颜色值。BufferedImage 喜欢假装图像是 RGB,无论数据存储为什么。您实际上可以了解内部DataBufferShort
(使用getTile(0, 0).getDataBuffer()
),但要弄清楚它的布局方式可能会很棘手。
如果您已经将像素放在 a 中short[]
,则更简单的解决方案可能是将它们复制到 a 中,int[]
而不是将其卡在 a 中MemoryImageSource
:
int[] buffer = /* pixels */;
ColorModel model = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] { 16 },
false, true, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
Image image = Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(VERTICAL_PIXELS, HORIZONTAL_PIXELS,
model, buffer, 0, VERTICAL_PIXELS));
这种方法的优点是您可以控制底层像素阵列。您可以对该数组进行更改并调用newPixels()
您的MemoryImageSource
,它会实时更新。它还为您提供了定义灰度以外的自己的调色板的完整功能:
int[] cmap = new int[65536];
for(int i = 0; i < 65536; ++i) {
cmap[i] = (((i % 10000) * 256 / 10000) << 16)
| (((i % 20000) * 256 / 20000) << 8)
| (((i % 40000) * 256 / 40000) << 0);
}
ColorModel model = new IndexColorModel(16, 65536, cmap, 0, false, -1, DataBuffer.TYPE_USHORT);
如果您只想在屏幕上显示图像,这种方法可以正常工作:
JFrame frame = new JFrame();
frame.getContentPane().add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
但是,如果您想将其写入文件并保留每像素一个短的格式(例如,加载到 Matlab 中),那么您就不走运了。您可以做的最好的是将其绘制成 aBufferedImage
并用 保存ImageIO
,这将保存为 RGB。
如果BufferedImage
最后确实需要 a,另一种方法是自己应用调色板,计算 RGB 值,然后将它们复制到图像中:
short[] data = /* your data */;
int[] cmap = /* as above */;
int[] rgb = new int[data.length];
for(int i = i; i < rgb.length; ++i) {
rgb[i] = cmap[data[i]];
}
BufferedImage image = new BufferedImage(
VERTICAL_PIXELS, HORIZONTAL_PIXELS,
BufferedImage.TYPE_INT_RGB);
image.setRGB(0, 0, VERTICAL_PIXELS, HORIZONTAL_PIXELS,
pixels, 0, VERTICAL_PIXELS);