создать разреженный BufferedImage в Java - PullRequest
3 голосов
/ 11 июня 2010

Мне нужно создать изображение с очень большим разрешением, но изображение относительно "разреженное", только некоторые области изображения должны быть нарисованы.

Например, со следующим кодом

/* 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); 

Размер PNG-изображения на конце, который я создал, составляет около 200 ~ 300 МБ.

Вопрос в том, как можно избежать создания 5GB BufferedImage в начале? Мне нужно изображение большого размера, но с очень редкой информацией о цвете.

Есть ли поток для BufferedImage, чтобы он не занимал так много памяти?

Ответы [ 2 ]

1 голос
/ 11 июня 2010

Есть ли причина не использовать отложенную инициализацию Map или аналогичную структуру, заполненную меньшими BufferedImages?

Редактировать: Это довольно специализированная структура данных.Если вы хотите рисовать изображения, разместите их разумным образом и примените к ним соответствующий AffineTransform.Затем вы можете просто перебрать коллекцию и нарисовать каждую из них и обнулить ее, или Flyweight, если она пуста сразу после этого.Я не знаю, как безболезненно объединить их все в PNG внутри Java.

0 голосов
/ 11 июня 2010

Ваш пример использует TYPE_INT_ARGB в качестве типа изображения, который составляет 4 байта на пиксель. Если изображение имеет ограниченное количество цветов, вы можете использовать другой тип изображения с меньшим количеством байтов на пиксель.

Это может уменьшить количество байтов на пиксель, но в лучшем случае это 1 байт на пиксель, который по-прежнему будет использовать более 1 ГБ.

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

...