Проблема в том, что setRGB()
хочет значение цвета 0xRRGGBB. BufferedImage любит притворяться, что изображение RGB, независимо от того, как хранятся данные. На самом деле вы можете добраться до внутреннего DataBufferShort
(с getTile(0, 0).getDataBuffer()
), но может быть сложно выяснить, как оно расположено.
Если у вас уже есть пиксели в short[]
, более простым решением может быть их копирование в int[]
вместо того, чтобы вставить его в 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), то вам не повезло. Лучшее, что вы можете сделать, это нарисовать его в BufferedImage
и сохранить его с ImageIO
, что сохранит как RGB.
Если вам определенно нужен BufferedImage
в конце, другой подход заключается в том, чтобы самостоятельно применить цветовую палитру, вычислить значения 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);