2010-06-11 15 views
3

Je dois créer une image avec une très grande résolution, mais l'image est relativement "clairsemée", seulement certaines zones de l'image doivent dessiner.créer une image buffered clairsemée en Java

Par exemple avec le code suivant

/* this take 5GB memory */ 

    final BufferedImage img = new BufferedImage(36000, 36000, BufferedImage.TYPE_INT_ARGB); 

/* draw something */ 

    Graphics g = img.getGraphics(); 
    g.drawImage(....); 

/* output as PNG */ 

    final File out = new File("out.png"); 
    ImageIO.write(img, "png", out); 

L'image PNG sur la fin que j'ai créé est seulement d'environ 200 ~ 300 Mo.

La question est comment puis-je éviter de créer un 5GB BufferedImage au début? J'ai besoin d'une image de grande dimension, mais avec des informations de couleurs très clairsemées.

Y a-t-il un Stream pour BufferedImage afin qu'il ne prenne pas autant de mémoire?

+0

PNG est compressé en utilisant l'algorithme DEFLATE comme dernière étape de sa création, il n'est donc pas surprenant qu'il soit considérablement plus petit que le 'BufferedImage'. – Powerlord

Répondre

1

Y a-t-il une raison pour ne pas utiliser une carte paresseuse initialisée ou une structure similaire remplie de plus petites images tamponnées?

Edit: C'est une structure de données assez spécialisée. Si vous voulez dessiner à travers des images, placez-les d'une manière raisonnable et appliquez un AffineTransform correspondant à chacun d'eux. Ensuite, vous pouvez juste itérer sur la collection et dessiner à chacun et annulez ou mouchez-le si elle est vide juste après. Je ne connais pas de manière non douloureuse de les combiner tous dans un PNG à l'intérieur de Java.

0

Votre exemple utilise TYPE_INT_ARGB comme type d'image qui est de 4 octets par pixel. Si l'image a un nombre limité de couleurs, vous pouvez utiliser un type d'image différent avec moins d'octets par pixel.

Cela pourrait réduire le nombre d'octets par pixel, mais le meilleur scénario est de 1 octet par pixel, qui utilisera encore plus de 1 Go.

Sinon, vous pourriez essayer de diviser le rendu en plusieurs images et de les fusionner séparément.