recorrer - manejo de imagenes en java
¿Convierta una matriz de píxeles en un objeto de imagen con ImageIO de Java? (6)
Como esta es una de las preguntas más votadas por etiqueta con ImageIO en SO, creo que todavía hay espacio para una mejor solución, incluso si la pregunta es antigua. :-)
Eche un vistazo a la clase BufferedImageFactory.java de mi proyecto de creación de imágenes open source en GitHub.
Con él, puedes simplemente escribir:
BufferedImage image = new BufferedImageFactory(image).getBufferedImage();
La otra cosa buena es que este enfoque, como el peor de los casos, tiene aproximadamente el mismo rendimiento (tiempo) que los ejemplos basados en PixelGrabber
ya están en este hilo. Para la mayoría de los casos comunes (generalmente JPEG), es aproximadamente el doble de rápido. En cualquier caso, usa menos memoria.
Como ventaja adicional, se conserva el modelo de color y el diseño de píxeles de la imagen original, en lugar de traducirlo a ARGB int con el modelo de color predeterminado. Esto podría ahorrar memoria adicional.
(PD: la fábrica también es compatible con submuestreo, región de interés y oyentes de progreso si alguien está interesado. :-)
Actualmente estoy convirtiendo una matriz de valores de píxeles (creados originalmente con un objeto java.awt.image.PixelGrabber) en un objeto de imagen utilizando el siguiente código:
public Image getImageFromArray(int[] pixels, int width, int height) {
MemoryImageSource mis = new MemoryImageSource(width, height, pixels, 0, width);
Toolkit tk = Toolkit.getDefaultToolkit();
return tk.createImage(mis);
}
¿Es posible lograr el mismo resultado utilizando clases de los paquetes de ImageO para que no tenga que usar AWT Toolkit?
Toolkit.getDefaultToolkit () no parece ser 100% confiable y algunas veces lanzará un AWTError, mientras que las clases ImageIO siempre deberían estar disponibles, por lo que estoy interesado en cambiar mi método.
He tenido éxito utilizando java.awt.Robot para tomar una captura de pantalla (o un segmento de la pantalla), pero para trabajar con ImageIO, tendrá que almacenarla en una Imagen Buffered en lugar de la fuente de la imagen de memoria. Luego puede llamar a un método estático de ImageIO y guardar el archivo. Pruebe algo como:
// Capture whole screen
Rectangle region = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capturedImage = new Robot().createScreenCapture(region);
// Save as PNG
File imageFile = new File("capturedImage.png");
ImageIO.write(capturedImage, "png", imageFile);
JavaDoc en BufferedImage.getData () dice: "un Raster que es una copia de los datos de la imagen".
Este código funciona para mí, pero dudo de su eficacia:
// Получаем картинку из массива.
int[] pixels = new int[width*height];
// Рисуем диагональ.
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
if (i == j) {
pixels[j*width + i] = Color.RED.getRGB();
}
else {
pixels[j*width + i] = Color.BLUE.getRGB();
//pixels[j*width + i] = 0x00000000;
}
}
}
BufferedImage pixelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
pixelImage.setRGB(0, 0, width, height, pixels, 0, width);
Puede crear la imagen sin usar ImageIO. Simplemente cree una Imagen Buffered utilizando un tipo de imagen que coincida con el contenido de la matriz de píxeles.
public static Image getImageFromArray(int[] pixels, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = (WritableRaster) image.getData();
raster.setPixels(0,0,width,height,pixels);
return image;
}
Cuando trabaje con PixelGrabber, no olvide extraer la información RGBA de la matriz de píxeles antes de llamar a getImageFromArray
. Hay un ejemplo de esto en el método handlepixel en el javadoc de PixelGrabber. Una vez que lo hagas, asegúrate de que el tipo de imagen en el constructor BufferedImage.TYPE_INT_ARGB
.
Tuve el mismo problema de que todos los demás intenten aplicar la respuesta correcta a esta pregunta, mi matriz int en realidad obtiene una excepción OutOfboundException donde lo arreglé agregando un índice más porque la longitud de la matriz tiene que ser de ancho * alto * 3 después de esto. no pude obtener la imagen, así que lo arreglé estableciendo el ráster en la imagen
public static Image getImageFromArray(int[] pixels, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = (WritableRaster) image.getData();
raster.setPixels(0,0,width,height,pixels);
image.setData(raster);
return image;
}
Y puedes ver la imagen si la muestras en una etiqueta en un jframe como este
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setVisible(true);
configurando la imagen en imageIcon (). El último consejo que puedes tratar de cambiar la imagen Buffered.TYPE_INT_ARGB a algo más que coincida con la imagen que obtuviste la matriz de este tipo es muy importante. Tenía una matriz de 0 y -1, así que utilicé este tipo BufferedImage.TYPE_3BYTE_BGR
Usando el ráster obtuve una ArrayIndexOutOfBoundsException
incluso cuando creé BufferedImage
con TYPE_INT_ARGB
. Sin embargo, usar el setRGB(...)
de BufferedImage
funcionó para mí.