Как уже отмечали другие, использование Java не обязательно является лучшим выбором здесь.
Если вы собираетесь использовать Java, ваш лучший выбор - при условии, что у вас недостаточно памяти, чтобы вы не могли прочитать весь набор данных в память несколько раз, а затем записать его снова, - это реализовать RenderedImage
с классом, который будет читать ваши PNG с диска по требованию. Если вы просто создадите свой новый BufferedImage, а затем попытаетесь записать его, программа записи PNG создаст дополнительную копию данных. Если вы создаете свой собственный RenderedImage, вы можете передать его ImageIO.write(myImageSet,"png",myFileName)
. Вы можете скопировать SampleModel
и ColorModel
информацию из вашего первого PNG - надеюсь, они все одинаковые.
Если вы делаете вид, что все изображение состоит из нескольких плиток (по одной плитке на исходное изображение), то ImageIO.write
создаст WritableRaster
, равный размеру всего набора данных изображения, и вызовет вашу реализацию RenderedImage.copyData
заполнить его данными. Если у вас достаточно памяти, это простой способ (потому что вы получаете огромный целевой набор данных и можете просто сбросить в него все данные вашего изображения - используя метод setRect(dx,dy,Raster)
) - и тогда вам не нужно переживай еще раз). Я не проверял, экономит ли это память, но мне кажется, что так и должно быть.
В качестве альтернативы, если вы притворяетесь, что все изображение представляет собой одну плитку, ImageIO.write
затем, используя getTile(0,0)
, запросит растр, соответствующий этому целому изображению. Таким образом, вы должны создать свой собственный растр, который, в свою очередь, заставляет вас создавать свой собственный DataBuffer. Когда я попробовал этот подход, минимальное использование памяти, которое успешно записало 15360x25600 RGB PNG, было -Xmx1700M
(в Scala, между прочим), что составляет чуть более 4 байтов на пиксель записанного изображения, поэтому очень мало служебной информации над одним полным изображением в памяти.
Сам по себе формат данных PNG не требует полного изображения в памяти - он будет нормально работать в блоках - но, к сожалению, реализация по умолчанию для устройства записи PNG предполагает, что в памяти будет весь массив пикселей.