Проблема здесь в том, что 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);
person
Russell Zahniser
schedule
07.01.2012