Probleme de performance avec objet Graphics d'une image.
Bonjour à tous,
Je développe une petite application de manipulation d'image en Java.
Dans un certain cas j'ai besoin de définir un "masque" par dessus une image. Le masque se dessine à la souris avec un gros pinceau (grossièrement) et s'affiche en transparence par dessus l'image.
On doit pouvoir modifier la couleur du masque si on en a envie (rouge par défaut).
Pour faire ça j'utilise une BufferedImage de type INT_ARGB que j'affiche par dessus l'image de base, j'appelle cette image "mask".
Pour dessiner dans mon masque j'ai le code suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
// get image graphics object
final Graphics2D g = (Graphics2D) mask.getGraphics();
// set no alpha
g.setComposite(AlphaComposite.Src);
// set color depending "remove" or "add" to mask
if (remove)
g.setColor(new Color(0x00000000, true));
else
g.setColor(new Color(0x80000000, true));
// draw cursor in the mask
g.fill(cursor); |
L'objet Cursor est un "Shape" que j'utilise pour déterminer la form du pinceau.
Ensuite pour l'affichage en temps que tel (image de base + le masque) j'utilise le code suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
public void paint(Graphics g)
{
// get graphics object of mask
final Graphics2D g2m = (Graphics2D) mask.getGraphics();
// we want to use source alpha information to mix color
g2m.setComposite(AlphaComposite.SrcIn);
// set mask color
g2m.setColor(getMaskColor());
// THIS IS SLOW !
g2m.fillRect(0, 0, mask.getWidth(), mask.getHeight());
final Graphics2D g2 = (Graphics2D) g;
// draw base image
g2.drawImage(image, null, 0, 0);
// draw mask
g2.drawImage(mask, null, 0, 0);
} |
Mon problème étant, comme vous l'avez peut être vu dans les commentaires du code, que la méthode "g2m.fillRect(...)" n'est pas assez rapide, elle devient même carrément lente sur de grosses images (5000 x 5000).
Je n'arrive pas à comprendre pourquoi puisque si j'essaie de faire la même opération sur l'objet "g2" alors ça reste très rapide même sur de très large surface (10000 x 10000) ! Je sais que l'objet "g2" représente le contexte graphique actuel mais je pense que Java 6 est capable de délivrer des "BufferedImage" accélérés dans la plupart des cas (et surtout pour une image de type INT_ARGB). J'ai essayé les différents xxxGraphicsDevice.createCompatibleImage(...) ou même createVolatileImage(...) mais sans succés :aie:
Honnêtement je suis sûr qu'il y des bien meilleurs méthodes pour afficher un masque coloré en transparence sur une image mais pour le moment je n'ai pas trouvé :cry: J'ai essayé d'utiliser une image de type BYTE_GRAY qui contenait 0x00 (transparent) et 0xFF (non transparent) pour le masque afin de réduire la charge mémoire du masque (après tout 1 bit devrait suffire) mais avec ce type d'image je n'ai pas été capable d'afficher le masque correctement puisque la méthode "g2m.setComposite(AlphaComposite.SrcIn)" n'a de sens qu'avec une information de type alpha ! De plus impossible d'afficher le masque autrement qu'en niveau de gris :?
Mais je me dis que j'ai du louper quelque chose, il n'est pas normal de devoir déclarer une image INT_ARGB pour afficher un pauvre masque mono couleur avec un degré de transparence fixé ! théoriquement 1 bit suffit ... pourtant je ne vois pas comment m'en sortir sans passer par une fichue image ARGB à un moment donné.
Merci à tout ceux qui pourront me venir en aide. Le plus important ça serait déjà de pouvoir corriger mon problème de performance sur le "g2m.fillRect(...)", ensuite la méthode, c'est secondaire... même si la méthode actuelle ne me convient pas vraiment ;)