Записать компонент свинга в большое изображение TIFF с помощью JAI

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

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

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

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

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

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

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

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

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

РЕДАКТИРОВАТЬ Я могу создать очень большой TIFF с использованием JAI, но JAI не поддерживает сжатие TIFF, поэтому размер файла составляет 92 МБ.

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

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

2 ответа

Решение

Мне пришлось загрузить и сохранить большой 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);

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

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

Другие вопросы по тегам