rectangle - Graphics.drawImage() en Java es EXTREMADAMENTE lento en algunas computadoras pero mucho más rápido en otras
ovalo java api (7)
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.
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.
¿Algunas ideas?
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 hacer que funcione más rápido en un monitor y luego lo desplazo a otro monitor cuando más de la mitad de la ventana está en el nuevo monitor, comienza a funcionar nuevamente. 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, muévelo al otro, por supuesto, resopla, pero si lo devuelvo al monitor original en el que hice el truco de cambio de tamaño, 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ño posible hasta el punto en que la imagen no se pueda ver realmente.
¿Podría ser esto un error en Java?
¿Cómo juzgas el poder 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 marcar 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ás usando los últimos controladores de Java y gráficos? Si su imagen es solo de 5Kx2.5K, lo único que puedo pensar es que lo hace sin aceleración de hardware.
Dado que Java usa OpenGL para hacer dibujos 2D , 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.
Hay varias cosas que podrían influir en el rendimiento aquí:
- RAM disponible
- velocidad de la CPU
- Tarjeta gráfica (a bordo o separada)
- Controlador gráfico
- Versión de Java
- Modo de video usado (resolución, bitdepth, soporte de aceleración)
EDITAR: echando un vistazo a la pregunta editada, me propongo verificar 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: cambie el tamaño de la imagen o divídala en fragmentos como lo propuso DNS. Nunca podrá ver toda la imagen tal como está en la pantalla.
Verifique 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.
¿Has probado el modo exclusivo de pantalla completa?
Esto podría ayudar: http://download.oracle.com/javase/tutorial/extra/fullscreen/index.html
Si está utilizando el Java de Sun intente algunas de las siguientes propiedades del sistema, ya sea como parámetros de línea de comando o las primeras líneas en main
sun.java2d.opengl=true //force ogl sun.java2d.ddscale=true //only when using direct3d sun.java2d.translaccel=true //only when using direct3d
se pueden ver más banderas en esta página
Mire sun.java2d.trace
que puede permitirle determinar la fuente de rendimiento de gráficos menos que deseable.
La ejecución de la escritura de una imagen en una pantalla se ve muy afectada por el formato en el 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 control sobre cómo se almacena la imagen, debe almacenarla en un formato que la pantalla esté buscando. Aquí hay un código de muestra:
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 valer la pena convertirla a un formato compatible, incluso si viene en otro formato.
Dibujar una imagen también será más lento si lo estás transformando a medida que dibujas, lo que la parte de "cambio de tamaño" de tu descripción me hace pensar que podrías 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.