2011-05-13 5 views
2

Je connais la différence d'utilisation de la mémoire entre octets, unsigned short et integer, mais quand il s'agit d'un BufferedImage, y a-t-il une différence de vitesse entre eux?

J'ai utilisé le type d'image dans mon code pour stocker des images, mais j'ai besoin d'une couche alpha. Utiliser BufferedImage me fournit ARGB, mais mon code est/considérablement/plus lent après avoir fait le changement du type Image (et il a seulement été changé pour quelques objets), donc je cherche toutes les améliorations de performance que je peux obtenir.

Je ne suis pas sûr de la stupidité d'une question, alors je vous remercie pour toute réponse.BufferedImage INT/4BYTE/USHORT

+0

Que dit votre profileur? – trashgod

+0

Que voulez-vous dire par le profileur? – Tanaki

+0

['jvisualvm'] (http://download.oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html), par exemple. – trashgod

Répondre

2

Tanaki,

j'ai trouvé que, en cas de besoin d'utiliser un canal alpha dans un BufferedImage, le mieux est de Prémultiplier le canal alpha. Par exemple:

 
// Create an ARGB image 
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB); 
Graphics2D g = bi.createGraphics(); 
// Fill the background (for illustration) 
g.setColor(Color.black); 
g.fill(new Rectangle(0, 0, 512, 512)); 

AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f)); 
// Keep the original composite 
Composite original = g.getComposite(); 
g.setComposite(alpha); 

// Paint with transparency 
Rectangle r = new Rectangle(100, 200, 50, 50); 
g.setColor(Color.magenta); 
g.fillRect(r); 
g.setComposite(original); 
// ... paint further shapes or images as necessary 
// ... 
g.dispose(); 

// Convert to a premultiplied alpha image for fast painting to a Canvas 
BufferedImage biPre = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB_PRE); 
Graphics2D gPre = biPre.createGraphics(); 
gPre.drawImage(bi, 0, 0, null); 
gPre.dispose(); 

// clean up: 
bi.flush(); 


// Now use biPre for painting to a Canvas, or a Component. 
// ... 

// Remember to flush it when done! 
biPre.flush(); 

La raison de la peinture d'abord à un TYPE_INT_ARGB est de faire en sorte que tous les alpha se peint comme prévu (non pré-multiplié chaque fois!). Ensuite, lorsque vous avez terminé, peignez toute l'image sur un TYPE_INT_ARGB_PRE, qui est alors en mesure d'amener les données à l'écran avec une bonne vitesse.

+0

Merci beaucoup, cela éclaircit mon problème. – Tanaki