2010-12-03 7 views
6

Cuando se trabaja con BufferedImage utilizando el setRGB y GetRGB métodos, me di cuenta de dos cosas:Trabajando en int de un BufferedImage [] píxeles gama

  1. la setRGB y getRGB métodos puede ser increíblemente lento en algunos sistemas (tanto como dos órdenes de magnitud más lento que modifiyng la matriz int []).

  2. No hay garantía de que un getRGB después de una setRGB devolverá el mismo píxel que ha pasado

Este último punto es básicamente bastante claro desde el JavaDoc de setRGB, que estados:

... Para imágenes con IndexColorModel, el índice con el color más cercano es elegido.

Seen puedo trabajar directamente en píxeles de un BufferedImage int [], que puedo tener acceso a por hacer, por ejemplo:

int[] a = ((DataBufferInt) tmp.getRaster().getDataBuffer()).getData(); 

Me preguntaba: ¿Hay inconvenientes conocidos/trampas cuando directamente manipulando píxeles en el int[]?

Respuesta

4

El objetivo de getData() que le da acceso a la matriz int de respaldo es precisamente para esta optimización, por lo que los beneficios probablemente compensen los inconvenientes.

Los inconvenientes dependen de cómo esté utilizando la imagen almacenada en el búfer. Si lo está dibujando en la pantalla mientras lo está editando, puede encontrar algunos artefactos en la pantalla (como los píxeles no coloreados en el tiempo), en cuyo caso debe considerar el doble almacenamiento en búfer (lo que implica copiar sobre toda la imagen para cada actualización).

+0

+1 pero ¿podría dar más información acerca de cómo debe/debería hacerse el doble almacenamiento en búfer? – SyntaxT3rr0r

+0

Cómo funciona el doble almacenamiento en búfer depende de varios factores, como lo que está mostrando, qué tan grande es, qué es el motor de gráficos, qué tan rápido una velocidad de actualización desea, si puede aprovechar lo que proporcionan sus gráficos tarjeta, etc. Pero una forma básica de hacerlo sería tener un búfer que modifique, y uno que muestre, copiando sobre el búfer modificado cuando haya terminado de hacer modificaciones. Una buena forma de hacerlo es copiar los datos en el búfer de modificación en un búfer de temperatura primero, de modo que la asignación del búfer de visualización al búfer de temperatura sea una operación rápida. –

+0

Hay un problema de lectores/escritores allí donde debe asegurarse de que no está tratando de mostrar un búfer que se está copiando. Si está haciendo todo esto en un solo hilo, puede salirse con la suya con algo como 'if (doneCopying) {displayBuf = tmpBuf; } draw (displayBuf); ' –

0

No estoy seguro de si esto es relevante para su pregunta, pero se encontrará con problemas cuando se creó BufferedImage utilizando el método getSubimage(int x, int y, int w, int h).

Devuelve una subimagen definida por una región rectangular especificada. El devuelto BufferedImage comparte la misma matriz de datos que la imagen original .

Los métodos getTileGridXOffset() y getTileGridYOffset() devolver el desplazamiento a continuación, a pesar de ser descrito como

Devuelve los x desplazamiento de la cuadrícula de azulejo en relación con el origen, Para ejemplo, la coordenada x de la ubicación de la baldosa (0, 0) Esto es siempre cero.

sino porque no se puede (por lo que yo sé) acceder al campo de la trama scanlineStride usted no será capaz de obtener el índice correcto para la matriz.