2011-05-12 3 views
3

J'ai un grand composant swing pour écrire en TIFF. Le composant est trop volumineux pour charger le TIFF en mémoire, donc je dois soit faire un gros BufferedImage qui est soutenu par un WritableRaster basé sur disque (comme mentionné here) ou utiliser JAI. JAI semble être la meilleure réponse, mis à part la confusion totale du projet. Par conséquent, est-ce que quelqu'un peut décrire les étapes pour écrire mon composant swing sur un TIFF en mosaïque sans manquer de mémoire?Écrire le composant swing sur une grande image TIFF en utilisant JAI

Taille de l'image sera peut-être 10000x700

Idéalement je voudrais créer une sorte d'image sur disque, et écrire des parties du composant à lui, chaque écriture étant effectués sur disque.

EDIT

Je pense que je pourrais faire avec un ImageWriter, mais je reçois un NoSuchElementException quand je l'appelle:

ImageWriter imageWriter = ImageIO.getImageWritersByFormatName("tif").next(); 

Je les pots de jai_code.jar et jai_core.jar sur mon chemin de classe, y a-t-il autre chose que je dois faire?

EDIT je peux créer un fichier TIFF très grand en utilisant JAI, mais ne supporte pas JAI compression TIFF, le fichier est de 92 Mo. Si j'installe JAI-ImageIO, je peux créer un fichier TIFF compressé à l'aide d'un ImageWriter, mais uniquement à partir d'un Raster ou BufferedImage, pour lequel je n'ai pas assez de mémoire.

Existe-t-il un moyen de faire une approche en deux étapes, utiliser JAI pour créer le grand TIFF, puis compresser le grand TIFF sans charger le tout en mémoire?

Répondre

2

J'ai dû charger et stocker un grand tiff (59392x40192px) avec JAI. Ma solution est: TiledImages.

J'ai utilisé un TiledImage parce que j'ai besoin de carreaux et de sous-images. Pour utiliser efficacement TiledImage, vous devez le construire avec la taille de tuile que vous préférez. JAI utilise un TileCache donc l'image entière ne sera pas en mémoire, quand ce n'est pas nécessaire.

Pour écrire le TiledImage dans un fichier utilisez l'option « writeTiled » (éviter OutOfMemory car il écrit tuile par tuile):

public void storeImage(TiledImage img, String filepath) { 
    TIFFEncodeParam tep = new TIFFEncodeParam(); 
    //important to avoid OutOfMemory 
    tep.setTileSize(256, 256); 
    tep.setWriteTiled(true); 
    //fast compression 
    tep.setCompression(TIFFEncodeParam.COMPRESSION_PACKBITS); 
    //write file 
    JAI.create("filestore", img, filepath, "TIFF", tep); 
} 

Il fonctionne très bien avec des images jusqu'à 690MB (compressé), pour des images plus grandes Je n'ai pas encore testé. Mais si vous travaillez sur WinXP 32 bits, vous ne pouvez pas avoir plus de taille HeapSpace 1280m, c'est toujours une limite de Java VM.

Mon TiledImage est construit avec un IndexedColorModel de mes données source d'images:

//here you create a ColorModel for your Image 
ColorModel cm = source.createColorModel(); 
//then create a compatible SampleModel, with the tilesize 
SampleModel sm = cm.createCompatibleSampleModel(tileWidth,tileHeight); 

TiledImage image = new TiledImage(0, 0, imageWidth, imageHeight, 0, 0, sm, cm); 
+0

comment créez-vous le TiledImage? –

+0

J'ai ajouté la création TiledImage ci-dessus. J'ai mis les échantillons directement dans l'image, car je dois charger px par px depuis ma source. Donc, j'ai toujours une tuile en mémoire pendant le chargement. – Indimental

1

J'ai eu la même situation et moi comme suit:

Cela m'a aidé à montrer et manipuler des images TIFF ~ 50Mo (de) 5000x5000px.

+0

Merci, D1i, je suis en train d'écrire une très grande image sur le disque. Je ne peux pas créer un BufferedImage assez grand, parce que je manque de mémoire. L'image finale, je veux vraiment avoir 10000 pixels de large. –

+0

Je vois, alors j'ai mal compris la question, O. Je suis impatient de répondre aussi bien, semble utile. – JMelnik

Questions connexes