Записать компонент свинга в большое изображение TIFF с помощью JAI - PullRequest
3 голосов
/ 12 мая 2011

У меня есть большой компонент свинга для записи в TIFF.Компонент слишком велик, чтобы загрузить TIFF в память, поэтому мне нужно либо создать большой BufferedImage, который поддерживается дисковым WritableRaster (как упоминалось здесь ), либо использовать JAI.

JAI кажется лучшим ответом, кроме полной путаницы в проекте.

Учитывая это, кто-то может наметить шаги для записи моего компонента свинга в мозаичный TIFF без исчерпания памяти?

Размер изображения может быть, возможно, 10000x700

В идеале я хотел бы создать какой-нибудь образ на основе диска и записать на него части компонента, каждая запись будет записана на диск.

РЕДАКТИРОВАТЬ

Я думаю, что я мог бы сделать это с ImageWriter, однако я получаю NoSuchElementException, когда я звоню:

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

У меня есть jai_code.jar и jai_core.jarjars на моем classpath, есть ли что-то еще, что мне нужно сделать?

EDIT Я могу создать очень большой TIFF с помощью JAI, но JAI не поддерживает сжатие TIFF, поэтому файл92 МБ.

Если я установлю JAI-ImageIO, я могу создать сжатый TIFF с помощью ImageWriter, но только из растра или BufferedImage, для которого у меня недостаточно памяти.

Есть ли какой-нибудь способчтобы сделать двухэтапный подход, использовать JAI для создания большого TIFF, а затем сжать большой TIFF, не загружая все это в память?

Ответы [ 2 ]

2 голосов
/ 16 июня 2011

Мне пришлось загрузить и сохранить большой tiff (59392x40192px) с JAI. Мое решение: TiledImages.

Я использовал TiledImage, потому что мне нужны плитки и изображения. Чтобы использовать эффективный TiledImage, вы должны создать его с вашим предпочтительным размером плитки. JAI использует TileCache, поэтому не весь образ будет в памяти, когда он не нужен.

Чтобы записать TiledImage в файл, используйте опцию «writeTiled» (избегайте OutOfMemory, потому что он пишет плитку по плитке):

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);
}

Отлично работает с изображениями до 690 МБ (сжатые), для больших изображений я еще не тестировал.

Но если вы работаете с 32-битной WinXP, у вас может не быть более 1280 м размера HeapSpace, это все равно ограничение Java VM.

Мой TiledImage собран с IndexedColorModel из моих данных источника изображения:

//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);
1 голос
/ 12 мая 2011

У меня была такая же ситуация, и я использовал следующие шаги:

Это помогло мне показать и манипулировать изображениями в формате TIFF ~ 50 МБ (5000x5000 пикселей).

...