2010-02-17 6 views
0

Je suis en train de concevoir un objet Canvas qui a été utilisé pour dessiner un objet BufferedImage de taille 228x262 pixels.Problèmes de performances avec Java 2D lors du dessin d'images tamponnées

Cette image a été dessinée à l'aide de la méthode Graphics2D.drawImage (...). Je fais une manipulation de la couleur de base de pixels dans des plages de décalage données. Un échantillon du code ci-dessous:.

for(int i = frameOffset; i < colorClock; i++) { 
    rgb[i] = new Color(this.colorBK).getRGB(); 
    } 

RBG est réglé à ce BufferedImage je change dans
Le problème est que le code est lent peinture.

Je crée l'image à l'aide de GraphicsConfiguration.createCompatibleImage et j'utilise la double mise en mémoire tampon via la stratégie de tampon.

Des lumières s'il vous plaît?

Merci sur adv.

+0

Par "peinture", voulez-vous dire après la conversion RVB? Ou la conversion ci-dessus se produit-elle sur chaque tick de rendu? – jevon

+0

Salut, la boucle de peinture se produit après une mise à jour est terminée. Je change d'abord les couleurs sur les pixels donnés, puis je Graphics2D.drawImage avec les nouvelles couleurs de pixel. – Leonardo

+1

Avez-vous essayé de le profiler? Quel IDE utilisez-vous? NetBeans a un profileur intégré, et je crois qu'il y a un plugin pour Eclipse. –

Répondre

0

Ne créez pas une nouvelle couleur uniquement pour extraire un entier RVB pour chaque pixel de votre image. Le seul constructeur de paramètres que je peux trouver pour Color est celui qui prend un RVB int - ne pouvez-vous pas utiliser directement colorBK?

De plus, si vous faites cette conversion sur chaque peinture qui sera lente; vous devriez seulement faire la conversion une fois.

+0

Salut Monkey, merci d'avoir répondu. En fait, je devrais changer la couleur de certains pixels après l'exécution d'un morceau de code. Le constructeur de couleur que j'utilise pour faire la conversion est vraiment celui-ci qui prend l'int RVB mais j'ai fait quelques changements et maintenant je peux l'utiliser directement.Tant que getRGB() sous le capot fait des décalages dans les bits des composants de couleur, il renvoie une valeur différente de celle que je passe au constructeur. Mais après des changements de code mineurs, je peux maintenant le faire directement. Je vous remercie. Mais encore, pas de gain de performance. – Leonardo

+0

@Leonardo: Le seul "changement" effectué par ce constructeur est de rendre la valeur alpha complètement opaque: 'value = 0xff000000 | rgb; ' C'est quelque chose que vous auriez pu faire facilement sans créer d'objet temp. –

+0

Homme facile, vous avez raison. Comme je l'ai déjà dit: "Mais après des changements mineurs de code, je peux maintenant le faire tout de suite". Je voulais dire que j'ai réussi à le faire sans aucun objet temp. Désolé pour mon manque de capacités d'expression. Mon point par la suite est que, même sans les temps, j'ai encore des problèmes de performance. Ce n'est pas un gros BufferedImage 262x228, mais il me faut du temps pour voir les lignes écrasées au moment du dessin. Merci pour les réponses. – Leonardo

1

Si vous exécutez la boucle à chaque fois que vous dessinez l'image, la boucle peut être le goulot d'étranglement. Il y a une allocation d'objet complètement inutile qui fera fonctionner le garbage collector assez souvent.

Je suppose que colorBK est int. Si c'est le cas, il vous suffit de créer et d'initialiser un objet Color et de lui demander de renvoyer une valeur rgb assignée à rgb array. Ce qui se passe réellement, c'est que vous affectez la valeur de colorBK dans le tableau rgb. Donc, une implémentation équivalente et plus efficace serait rgb [i] = colorBK.

Pour optimiser cela encore plus, vous pouvez affecter la valeur de colorBK à une variable locale finale. Cela éviterait de récupérer la valeur du champ encore et encore. Ainsi, la boucle pourrait ressembler à ceci:

final int color = colorBK; 
for(int i = frameOffset; i < colorClock; i++) { 
    rgb[i] = color; 
} 

Pour obtenir encore plus de gain de performance, vous devez penser que s'il y a des façons complètement différentes de le faire. Comme l'exemple ci-dessus change juste quelques pixels en certaine couleur, je pourrais supposer que ceci pourrait être fait avec une image et un couple de fillRects.

Vous devez donc remplir un rect derrière l'image avec la couleur souhaitée (dans ce cas, colorBK). Si l'image a des pixels transparents dans ces zones, les changements de boucles ci-dessus restent inchangés dans la toile et le même effet est obtenu. Cela peut être plus efficace car les méthodes graphiques sont mieux optimisées et n'impliquent pas une utilisation intensive des tableaux.

+0

Et comme d'autres l'ont souligné dans ce fil, si la couleur est constante, cela doit être fait une seule fois lorsque l'image est chargée et non pas pendant chaque peinture. – Lauri

+0

Salut Lauri. En fait, les méthodes graphiques devraient être meilleures, mais je l'ai déjà essayé avec fillRects auparavant et c'était beaucoup plus lent. Mais comme le code est tout aussi différent maintenant que ce temps, j'ai rempli fillRects à la place du dessin BufferedImage mais la performance est restée inchangée. Cependant, je n'ai pas essayé le truc derrière fillRect et je vais le vérifier. Je vous remercie. Je dois probablement repenser tout le système de dessin. – Leonardo

Questions connexes