Puedo ver muchas respuestas, sin abordar realmente las tres preguntas del PO.
1) Una palabra sobre el rendimiento: las matrices de bytes son probablemente poco eficientes a menos que pueda usar un orden de bytes de píxeles exacto que coincida con la resolución actual y la profundidad de color de sus adaptadores de pantalla.
Para lograr el mejor rendimiento de dibujo, simplemente convierta su imagen en una Imagen Buffered que se genera con un tipo correspondiente a su configuración gráfica actual. Consulte createCompatibleImage en https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
Estas imágenes se almacenarán en caché automáticamente en la memoria de la tarjeta de visualización después de dibujar varias veces sin ningún esfuerzo de programación (esto es estándar en Swing desde Java 6) y, por lo tanto, el dibujo real tomará una cantidad de tiempo insignificante, si no cambió la imagen .
La alteración de la imagen vendrá con una transferencia de memoria adicional entre la memoria principal y la memoria de la GPU, que es lenta. Evite "volver a dibujar" la imagen en una BufferedImage, por lo tanto, evite hacer getPixel y setPixel por todos los medios.
Por ejemplo, si está desarrollando un juego, en lugar de atraer a todos los actores del juego a una BufferedImage y luego a un JPanel, es mucho más rápido cargar a todos los actores como BufferedImages más pequeños y dibujarlos uno por uno en su código JPanel en su posición correcta: de esta manera no hay transferencia de datos adicional entre la memoria principal y la memoria de la GPU, excepto la transferencia inicial de las imágenes para el almacenamiento en caché.
ImageIcon usará una BufferedImage debajo del capó, pero básicamente la asignación de una BufferedImage con el modo gráfico adecuado es la clave, y no hay ningún esfuerzo para hacerlo correctamente.
2) La forma habitual de hacer esto es dibujar una BufferedImage en un método anulado de paintComponent del JPanel. Aunque Java admite una buena cantidad de beneficios adicionales, como cadenas de búfer que controlan VolatileImages en caché en la memoria de la GPU, no hay necesidad de usar ninguno de estos, ya que Java 6 hace un trabajo razonablemente bueno sin exponer todos estos detalles de la aceleración de la GPU.
Tenga en cuenta que la aceleración de GPU puede no funcionar para ciertas operaciones, como estirar imágenes translúcidas.
3) No agregar. Solo píntalo como se mencionó anteriormente:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
"Agregar" tiene sentido si la imagen es parte del diseño. Si necesita esto como una imagen de fondo o primer plano que llena el JPanel, simplemente dibuje paintComponent. Si prefiere preparar un componente Swing genérico que pueda mostrar su imagen, entonces es la misma historia (puede usar un JComponent y anular su método paintComponent), y luego agregar esto a su diseño de componentes GUI.
4) Cómo convertir la matriz a una imagen almacenada en búfer
La conversión de sus conjuntos de bytes a PNG y luego su carga requieren muchos recursos. Una mejor manera es convertir su matriz de bytes existente a una imagen almacenada.
Para eso: no lo use para bucles ni copie píxeles. Eso es muy muy lento. En lugar:
- aprenda la estructura de bytes preferida de BufferedImage (hoy en día es seguro asumir RGB o RGBA, que es de 4 bytes por píxel)
- aprenda la línea de escaneo y el tamaño de escaneo en uso (por ejemplo, puede tener una imagen de 142 píxeles de ancho, pero en la vida real se almacenará como una matriz de bytes de 256 píxeles de ancho, ya que es más rápido procesar eso y enmascarar los píxeles no utilizados por el hardware de la GPU )
- luego, una vez que haya creado una matriz de acuerdo con estos principios, el método de matriz setRGB de BufferedImage puede copiar su matriz a BufferedImage.
MemoryImageSource
que convertirlos a formato JPEG o PNG y luego leer con laImageIO
mayoría de las respuestas. Puede obtener unaImage
de unaMemoryImageSource
construida con sus datos de imagen mediante el usocreateImage
y mostrar como se sugiere en una de las respuestas.