2009-03-18 3 views
15

J'ai un problème étrange, essentiellement en Java Graphics.drawImage() est extrêmement lent sur certains ordinateurs et plus rapide sur d'autres. Ce n'est pas lié à la puissance des ordinateurs non plus, certains ordinateurs plus faibles fonctionnent bien alors que d'autres plus puissants semblent s'étrangler à l'appel drawImage.Graphics.drawImage() en Java est extrêmement lent sur certains ordinateurs et beaucoup plus rapide sur d'autres

Il peut ou non être lié à la largeur et la hauteur, j'ai une très, très grande largeur et la hauteur définie (quelque chose comme 5000 par 2500). Je ne pense pas que ce soit le problème, sauf comme je l'ai dit, il fonctionne en temps réel sur certains ordinateurs et plus lent sur d'autres et ne semble pas être lié à la puissance relative des ordinateurs.

Les deux ordinateurs ont la même version de Java, les deux utilisent Vista. On a un Core 2 Duo de 1,83 ghz avec 1 Go de RAM et des graphiques embarqués (tout fonctionne bien), l'autre a un core 2 de 2,53 ghz avec un 9600GS (les derniers pilotes nVidia) et 4 Go de RAM et il fait littéralement appel à l'appel drawImage.

Des idées?

edit: ok c'est vraiment bizarre, je dessine l'image dans une fenêtre de Swing, maintenant quand je redimensionne la fenêtre et la rend vraiment petite, l'image est réduite et elle devient petite. Soudain, tout se passe bien, quand je le redimensionne à la taille qu'il était avant qu'il ne fonctionne encore en douceur! Il a également plusieurs problèmes de moniteur, si je fais l'astuce de redimensionnement pour le faire fonctionner plus rapidement sur un moniteur, puis le faire défiler sur un autre moniteur lorsque plus de la moitié de la fenêtre est dans le nouveau moniteur. Je dois redimensionner la fenêtre pour la redimensionner puis la ramener à sa taille d'origine pour récupérer la vitesse.

Si je fais le tour de redimensionnement sur un écran, déplacez-le vers l'autre il de Chugs de cours, mais si je retourne revenir à l'écran d'origine sur lequel je l'ai fait le tour de Redimensionner cela fonctionne 100%

Si j'ai deux fenêtres pivotantes ouvertes (affichant la même image), elles fonctionnent toutes deux lentement, mais si je fais l'opération de redimensionnement sur une fenêtre, elles se déroulent toutes deux en douceur (mais ce n'est pas toujours le cas).

* quand je dis redimensionner la fenêtre, je veux dire le rendre aussi petit que possible au point où l'image ne peut pas être réellement vu.

Serait-ce un bug dans Java peut-être?

+0

Quel genre d'image est, et quelles versions du JDK sont sur les ordinateurs? –

+0

Je pense que je vois le même problème.C'est JDK 8 sur XP (ouais je sais) et un écran Hi-Color. Il faut quelques secondes pour rendre une image bufferedImage contenant une capture d'écran en plein écran - mais seulement la seconde (!) Fois que le composant est dessiné. Les appels suivants à drawImage sont à nouveau instantanés. Peut-être que la conversion a lieu en interne? Tout à fait déroutant dans l'ensemble, et pas vraiment acceptable qu'une simple conversion de couleur prend autant de temps (si c'est la raison). –

Répondre

2

Il y a plusieurs choses qui pourraient influencer la performance ici:

  • RAM disponible
  • vitesse CPU
  • Carte graphique (à bord ou séparée)
  • pilote graphique
  • Java Version
  • Mode vidéo utilisé (résolution, bitdepth, accélération)

EDIT: En jetant un oeil à la question éditée, je proposerais de vérifier si le système 9600GS a les plus nouveaux conducteurs de NVIDIA installés. J'ai récemment installé un pilote pour une carte graphique intégrée Intel qui a remplacé le pilote Windows générique et a rendu les fenêtres mobiles, en regardant des vidéos, en navigant etc. beaucoup plus rapidement.

Toutes les autres caractéristiques sont bonnes. Peut-être que Java ne détecte pas le 9600GS et n'utilise pas l'accélération matérielle, mais j'en doute.

Vérifiez également la configuration du système d'exploitation. Sous Windows, vous pouvez désactiver l'accélération matérielle à des fins de débogage.

Bien sûr, la meilleure façon de gérer cela serait de changer votre code - redimensionner l'image ou le diviser en morceaux comme le proposait le DNS. Vous ne serez jamais capable de voir toute l'image telle qu'elle est sur l'écran.

+0

Un ordinateur est vieux, nous parlons vraiment vieux et l'autre est nouveau et haut de gamme, il a un meilleur CPU, RAM, graphiques mais la même version de Java. Aussi, j'ai peut-être eu tort avec le 50.000x25.000, il est en fait 5000x2500. –

2

Comment jugez-vous le pouvoir des ordinateurs? Une image 32 bits de 50 x 25 K prend plus de 4,5 Go de mémoire vive (50000 * 25000 * 4 octets). Si un ordinateur a plus de RAM qu'une autre, cela peut faire une énorme différence de vitesse, car il n'aura pas besoin d'échanger autant de fois sur le disque. Vous devriez envisager de saisir des sous-sections de l'image et de travailler avec celles-ci, au lieu de tout.

Editer: Utilisez-vous les derniers pilotes graphiques Java &? Si votre image est seulement 5Kx2.5K, la seule chose que je peux penser est qu'il le fait sans aucune accélération matérielle.

+0

non je voulais dire 5000x2000, j'ai trouvé le nombre 50000x20000 plutôt grand alors réalisé que je mettais un 0 supplémentaire à la fin des chiffres, je devrais peut-être lentement devenir aveugle ou quelque chose. –

1

Vérifiez les paramètres de l'écran. Mon pari est que la profondeur de pixel est différente sur les deux systèmes, et que le lent a une profondeur de pixel impair liée à l'objet d'image que vous essayez d'afficher.

0

Depuis Java uses OpenGL to do 2D drawing, les performances de votre application seront affectées par les performances OpenGL de la puce graphique dans l'ordinateur respectif. La prise en charge d'OpenGL diminue dans l'industrie 3D, ce qui signifie que (ironiquement) les nouvelles puces peuvent être plus lentes au rendu OpenGL que les plus anciennes - non seulement en raison du matériel mais aussi des pilotes.

4

Si vous utilisez Java essayer quelques-unes des propriétés système suivantes de soleil, que ce soit en tant que paramètres de ligne de commande ou les premières lignes dans les principales

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

plus drapeaux peuvent être consultés à this page

Regardez sun.java2d.trace ce qui peut vous permettre de déterminer la source de performances graphiques moins que souhaitable.

22

La performance de l'écriture d'une image sur un écran est très affectée par le format dans lequel l'image est stockée. Si le format est le même que la mémoire de l'écran le veut, il peut être très rapide; si ce n'est pas le cas, une conversion doit être faite, parfois pixel par pixel, ce qui est très lent.

Si vous avez un contrôle sur la façon dont l'image est stockée, vous devez l'enregistrer dans un format que l'écran recherche. Voici quelques exemples de code:

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 vous allez dessiner l'image plusieurs fois il peut être utile de convertir en un format compatible, même s'il est venu dans un autre format. Le dessin d'une image sera également plus lent si vous le transformez au fur et à mesure que vous dessinez, ce que la partie «redimensionnement» de votre description me fait penser que vous pourriez être. Encore une fois, faites le redimensionnement une fois (lorsque la fenêtre est redimensionnée) et mettez en cache l'image redimensionnée et compatible afin qu'elle puisse être redessinée rapidement.

+3

cela a fonctionné brillamment pour moi, merci! J'ai utilisé ce code en même temps que getRGB/setRGB pour convertir mon image en tampon – Sam

+1

Grand merci! Bonne réponse, m'a beaucoup aidé. Envisagez de l'accepter. –

+0

Merci beaucoup pour ça! Je suis passé de ~ 17fps à 40 –

Questions connexes