Estoy buscando la forma más rápida de obtener datos de píxeles (en el formulario int[][]
) de un archivo BufferedImage
. Mi objetivo es poder abordar el píxel (x, y)
de la imagen usando int[x][y]
. Todos los métodos que he encontrado no hacen esto (la mayoría devuelve int[]
s).
java
bufferedimage
javax.imageio
Ryyst
fuente
fuente
getRGB
ysetRGB
directamente?getRGB
ysetRGB
directamente.Respuestas:
Estaba jugando con este mismo tema, que es la forma más rápida de acceder a los píxeles. Actualmente conozco dos formas de hacer esto:
getRGB()
método de BufferedImage como se describe en la respuesta de @ tskuzzy.Accediendo a la matriz de píxeles directamente usando:
Si está trabajando con imágenes grandes y el rendimiento es un problema, el primer método no es en absoluto el camino a seguir. El
getRGB()
método combina los valores alfa, rojo, verde y azul en un único int y luego devuelve el resultado, que en la mayoría de los casos hará lo contrario para recuperar estos valores.El segundo método devolverá los valores rojo, verde y azul directamente para cada píxel, y si hay un canal alfa, agregará el valor alfa. Usar este método es más difícil en términos de cálculo de índices, pero es mucho más rápido que el primer enfoque.
En mi aplicación, pude reducir el tiempo de procesamiento de los píxeles en más del 90% simplemente cambiando del primer enfoque al segundo.
Aquí hay una comparación que configuré para comparar los dos enfoques:
¿Puedes adivinar la salida? ;)
fuente
convertTo2DUsingGetRGB
yconvertTo2DWithoutUsingGetRGB
. La primera prueba dura en promedio 16 segundos. La segunda prueba dura en promedio 1,5 segundos. Al principio pensé que la "s" y la "ms" eran dos columnas diferentes. @Mota, gran referencia.BufferedImage
.type
Ej.TYPE_INT_RGB
O los entrantesTYPE_3BYTE_BGR
y manejarlos de forma adecuada. Esta es una de las cosas quegetRGB()
hace por ti, que lo hace más lento :-(|=
lugar de+=
combinar los valores en el método 2?¿Algo como esto?
fuente
BufferedImage
¿almacenaría los píxeles usando una matriz int 2D, de todos modos?Raster
búfer de datos del ', lo que definitivamente es algo bueno ya que da como resultado una aceleración de despeje.Descubrí que la respuesta de Mota me dio un aumento de velocidad de 10 veces, así que gracias Mota.
Envolví el código en una clase conveniente que toma BufferedImage en el constructor y expone un método getRBG (x, y) equivalente que lo convierte en un reemplazo para el código que usa BufferedImage.getRGB (x, y)
fuente
La respuesta de Mota es excelente a menos que su Imagen de búfer provenga de un mapa de bits monocromo. Un mapa de bits monocromo tiene solo 2 valores posibles para sus píxeles (por ejemplo, 0 = negro y 1 = blanco). Cuando se utiliza un mapa de bits monocromo,
call devuelve los datos sin procesar de Pixel Array de tal manera que cada byte contiene más de un píxel.
Entonces, cuando usa una imagen de mapa de bits monocromo para crear su objeto BufferedImage, este es el algoritmo que desea usar:
fuente
Si es útil, intente esto:
fuente
Aquí hay otra implementación de FastRGB que se encuentra aquí :
¿Que es esto?
Leer una imagen píxel a píxel a través del método getRGB de BufferedImage es bastante lento, esta clase es la solución para esto.
La idea es que construya el objeto alimentándolo con una instancia de BufferedImage, y lea todos los datos a la vez y los almacene en una matriz. Una vez que desee obtener píxeles, llame a getRGB
Dependencias
Consideraciones
Aunque FastRGB hace que la lectura de píxeles sea mucho más rápida, podría conducir a un alto uso de memoria, ya que simplemente almacena una copia de la imagen. Entonces, si tiene una imagen de búfer de 4 MB en la memoria, una vez que cree la instancia de FastRGB, el uso de la memoria se convertiría en 8 MB. Sin embargo, puede reciclar la instancia de BufferedImage después de crear FastRGB.
Tenga cuidado de no caer en OutOfMemoryException cuando lo use en dispositivos como teléfonos Android, donde la RAM es un cuello de botella
fuente
Esto funcionó para mí:
fuente
i
?