2009-03-18 10 views
15

Tengo un problema extraño, básicamente en Java Graphics.drawImage() es extremadamente lento en algunas computadoras y más rápido en otras. Esto tampoco está relacionado con la potencia de las computadoras, algunas computadoras más débiles funcionan bien, mientras que algunas más fuertes parecen bloquearse en la llamada a drawImage.Graphics.drawImage() en Java es EXTREMADAMENTE lento en algunas computadoras pero mucho más rápido en otras

Puede o no estar relacionado con el ancho y la altura, tengo un ancho y una altura muy, muy grandes definidos (algo así como 5000 por 2500). No creo que sea el problema, excepto como dije que funciona en tiempo real en algunas computadoras y más lento en otras y no parece estar relacionado con la potencia relativa de las computadoras.

Ambas computadoras tienen la misma versión de Java, ambas usan Vista. Uno tiene un Core 2 Duo de 1.83 ghz con 1 gb de RAM y gráficos integrados (todo funciona bien), el otro tiene un dúo core 2.53 ghz con un 9600GS (los últimos controladores nVidia) y 4 gb de RAM y literalmente resuena en la llamada drawImage.

¿Alguna idea?

edit: ok esto es realmente extraño, estoy dibujando la imagen en una ventana en Swing, ahora cuando cambio el tamaño de la ventana y la hago realmente pequeña, la imagen también se reduce y se vuelve pequeña. ¡De repente, todo funciona sin problemas, cuando lo vuelvo a escalar hasta el tamaño que tenía antes de que siga funcionando sin problemas!

También tiene múltiples problemas de monitor, si hago el truco de cambio de tamaño para hacerlo funcionar más rápido en un monitor y luego desplazarlo a otro monitor cuando más de la mitad de la ventana está en el nuevo monitor, vuelve a funcionar. Tengo que cambiar el tamaño de la ventana de nuevo a pequeño y luego volver a su tamaño original para recuperar la velocidad.

Si hago el truco de cambio de tamaño en un monitor, moverlo hacia el otro es de Chugs curso, pero si vuelvo de nuevo a la pantalla original en el que hice el truco de cambio de tamaño que funciona al 100%

Si tengo dos ventanas abatibles abiertas (mostrando la misma imagen) ambas funcionan con lentitud, pero si hago el truco de cambio de tamaño en una ventana, ambas comienzan a funcionar sin problemas (sin embargo, este no es siempre el caso).

* cuando digo redimensionar la ventana quiero decir que sea lo más pequeña posible hasta el punto en que la imagen no se pueda ver realmente.

¿Podría ser esto un error en Java?

+0

¿Qué tipo de imagen es, y qué versiones del JDK están en los ordenadores? –

+0

Creo que estoy viendo el mismo problema.Este es JDK 8 en XP (sí lo sé) y una pantalla Hi-Color. Se tarda unos segundos en renderizar una Imagen Buffered que contiene una captura de pantalla completa, pero solo la segunda (!) Vez que se dibuja el componente. Las llamadas posteriores a drawImage vuelven a ser instantáneas. Tal vez alguna conversión se lleva a cabo internamente? Bastante confuso en general, y no es realmente aceptable que una conversión de color simple tome tanto tiempo (si es la razón). –

Respuesta

2

Hay varias cosas que podrían influir en el rendimiento aquí:

  • RAM disponible
  • velocidad de la CPU
  • Tarjeta gráfica (a bordo o por separado)
  • controlador gráfico versión
  • Java
  • Modo de video usado (resolución, bitdepth, soporte de aceleración)

EDITAR: Echando un vistazo a la pregunta editada, propongo comprobar si el sistema 9600GS tiene instalados los controladores NVIDIA más nuevos. Hace poco instalé un controlador para una tarjeta gráfica integrada de Intel que reemplazó el controlador genérico de Windows e hizo que las ventanas se movieran, mirara videos, navegara, etc. mucho más rápido.

Todas las demás especificaciones se ven bien. Tal vez Java no detecta el 9600GS y no utiliza aceleración de hardware, pero lo dudo.

También verifique la configuración del sistema operativo. En Windows, puede desactivar la aceleración de hardware con fines de depuración.

Por supuesto, la mejor manera de manejar esto sería cambiar el código, cambiar el tamaño de la imagen o dividirla en fragmentos como lo propuso DNS. Nunca podrá ver toda la imagen tal como está en la pantalla.

+0

Una computadora es vieja, estamos hablando muy viejo y la otra es nueva y de gama alta, tiene mejor CPU, RAM, gráficos pero la misma versión de Java. También podría haber estado equivocado con el 50,000x25,000, en realidad es 5000x2500. –

2

¿Cómo juzga la potencia de las computadoras? Una imagen de 50x25 K de 32 bits requiere más de 4,5 GB de RAM para almacenar en la memoria (50000 * 25000 * 4 bytes). Si una computadora tiene más RAM que otra, eso puede hacer una gran diferencia en la velocidad, ya que no tendrá que cambiar al disco con tanta frecuencia. Debería considerar tomar subsecciones de la imagen y trabajar con ellas, en lugar de todo.

Editar: ¿Está utilizando los últimos controladores de gráficos Java &? Si su imagen es solo de 5Kx2.5K, lo único que puedo pensar es que lo hace sin aceleración de hardware.

+0

no Me refería a 5000x2000, encontré el número 50000x20000 bastante grande y luego me di cuenta de que estaba poniendo un 0 extra al final de los números, es posible que lentamente me quede ciego o algo así. –

1

Compruebe la configuración de la pantalla. Mi apuesta es que la profundidad del píxel es diferente en los dos sistemas, y que el lento tiene una profundidad de píxel impar relacionada con el objeto de imagen que está tratando de mostrar.

0

Desde Java uses OpenGL to do 2D drawing, el rendimiento de su aplicación se verá afectado por el rendimiento de OpenGL del chip gráfico en la computadora respectiva. El soporte para OpenGL está disminuyendo en la industria 3D, lo que significa que (irónicamente) los chips más nuevos pueden ser más lentos en la representación de OpenGL que los anteriores, no solo por el hardware sino también por los controladores.

4

Si está utilizando Java de Sun probar algunas de las siguientes propiedades del sistema, ya sea como parámetros de línea de comandos o las primeras líneas principales

 
sun.java2d.opengl=true //force ogl 
sun.java2d.ddscale=true //only when using direct3d 
sun.java2d.translaccel=true //only when using direct3d 

más banderas se pueden ver en this page

mirada a sun.java2d.trace que puede permitirle determinar la fuente de rendimiento de gráficos menos que deseable.

22

El rendimiento de la escritura de una imagen en una pantalla se ve muy afectado por el formato en que se almacena la imagen. Si el formato es el mismo que la pantalla quiere, entonces puede ser muy rápido; si no es así, se debe realizar una conversión, a veces píxel por píxel, que es muy lento.

Si tiene algún control sobre cómo se almacena la imagen, debe almacenarla en un formato que la pantalla está buscando. Aquí hay un código de ejemplo:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice device = env.getDefaultScreenDevice(); 
    GraphicsConfiguration config = device.getDefaultConfiguration(); 
    BufferedImage buffy = config.createCompatibleImage(width, height, Transparency.TRANSLUCENT); 
    Graphics g = buffy.getGraphics(); 

Si va a dibujar la imagen muchas veces puede ser digno de convertir a un formato compatible incluso si se trataba de algún otro formato.

El dibujo de una imagen también será más lento si lo está transformando a medida que dibuja, lo que la parte de 'cambio de tamaño' de su descripción me hace pensar que podría ser. De nuevo, realice el cambio de tamaño una vez (cuando la ventana cambie de tamaño) y guarde en caché la imagen ajustada y compatible para que pueda volver a dibujarse rápidamente.

+3

esto funcionó de maravilla para mí, ¡gracias! Usé este código junto con getRGB/setRGB para convertir mi BufferedImage – Sam

+1

¡Muchas gracias! Una gran respuesta, me ayudó mucho. Considera aceptarlo. –

+0

¡Muchas gracias por esto! Pasé de ~ 17 fps a 40 –

Cuestiones relacionadas