Pregunta

He hecho esta pregunta antes, pero quería reformular / aclarar algunos puntos y ampliar sobre ella. Tengo una pieza de código que transforma un BufferedImage usando un AffineTransform.

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage = op.filter(displayImage, null);

Este código funciona bien, sin embargo, causa una acumulación de memoria. En concreto, cada vez que esta pieza de código se llama más la memoria se almacena para arriba. He tratado de la otra forma de filtro también.

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage2 = op.createCompatibleDestImage(displayImage, displayImage.getColorModel());
op.filter(displayImage, displayImage2);

Sin embargo, esto es mucho más lenta que la primera versión. Quiero que la velocidad de la primera versión con el uso de la memoria de la segunda.

  1. ¿Cómo puedo limpiar después de la primera versión? En concreto, donde se almacenan los BufferedImages intermedios, y cómo puedo eliminarlos?
  2. ¿Por qué es la segunda versión más lenta que la primera? ¿Qué puedo hacer para acelerarlo?

Gracias por su ayuda !!!

¿Fue útil?

Solución

¿Cómo le va displayImage y lo ColorModel está usando?

Si es una IndexColorModel, que pueden explicar mucho.

El primer fragmento de código devolverá un BufferedImage usando un DirectColorModel. Eso requerirá 4 bytes por píxel vs normalmente de 1 byte por píxel de una imagen indexada. Eso. 1: 4 expansión podría ser la causa de su condición de falta de memoria

El segundo fragmento de código realiza una BufferedImage con el mismo modelo que la fuente. Cuando ese es un IndexColorModel y la interpolación no se NEAREST_NEIGHBOR, la llamada filter() creará un BufferedImage temporal con un DirectColorModel. Utilizará que a medida que el destino de la operación de filtro, entonces requantize el buffer temporal y atraerla hacia su displayImage2. Así, el doble de bitblits.

Si sólo está haciendo una transformación única, yo diría que ir con la segunda forma.

Si estás haciendo múltiples operaciones, asigne un par de BufferedImages con un DirectColorModel. suficientemente grande para contener la peor imagen. Dibuje que la imagen de origen en uno de ellos y realizar sus filtros de ida y vuelta entre ellos. Luego, cuando haya terminado, use un ColorConvertOp a requantize de nuevo a una imagen indexada. De esta manera sólo se necesita para convertir el color en lugar de una vez en cada llamada filtro.

Otros consejos

Estoy de acuerdo con el comentario de que a menos que usted está recibiendo OutOfMemoryErrors, entonces esto es una cosa normal y el GC recogerá las imágenes cuando lo considere conveniente. Aquí está una prueba de tontos a veces lo hice cuando tenía una preocupación: poner esto en bucle en una función principal y ver el uso de memoria en un generador de perfiles (que debe hacer un patrón de zig-zag similar o algo así), pero no siempre será capaz de completar con éxito.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top