El problema aquí es que setRGB()
quiere un valor de color 0xRRGGBB. A BufferedImage le gusta simular que la imagen es RGB, sin importar cómo se almacenan los datos. De hecho, puede obtener el DataBufferShort
interno (con getTile(0, 0).getDataBuffer()
), pero puede ser difícil averiguar cómo se presenta.
Si ya tiene sus píxeles en una short[]
, una solución más simple podría ser para copiarlos en un int[]
lugar un atasco en una 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));
La ventaja de este enfoque es que permite controlar la matriz de píxeles subyacente. Podría hacer cambios en esa matriz y llamar al newPixels()
en su MemoryImageSource
, y se actualizaría en vivo. También le da el poder total para definir su propia paleta aparte de escala de grises:
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);
Este enfoque funciona bien si sólo desea visualizar la imagen en la pantalla:
JFrame frame = new JFrame();
frame.getContentPane().add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Sin embargo, si desea para escribirlo en un archivo y conservar el formato de uno-corto por píxel (por ejemplo, para cargarlo en Matlab), entonces no tiene suerte. Lo mejor que puede hacer es pintarlo en un BufferedImage
y guardarlo con ImageIO
, que se guardará como RGB.
Si definitivamente necesita un BufferedImage
al final, otro enfoque es aplicar el color paleta de sí mismo, el cálculo de los valores RGB, y luego copiarlos en la imagen:
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);
lo hacía, se dio cuenta de mi código de dibujo es FUBAR con ArrayOutOfBounds excepciones en todas partes. Mirándolo, parece que funcionaría bien. Todo lo que necesito hacer es generarlo como .png, lo que he hecho (afortunadamente) con éxito. Marcaré esto como correcto porque parece que funcionaría bien. –
Cuando esto pone los píxeles en la imagen, ¿los dibuja en líneas verticales que comienzan en la izquierda y van a la derecha o horizontal que comienzan en la parte superior y bajan? Debido a que mi código de trabajo parcial tiene la imagen girada 90 grados en el sentido de las agujas del reloj y no creo que sea culpa del dibujo. –
¡No importa!Tuve que cambiar el 200 en la parte MemoryImageSource a HORIZONTAL_PIXELS. Funciona genial, gracias! –