libvips может сделать это быстро и с небольшим объемом памяти, но, к сожалению, нет удобной привязки Java.Вам нужно было бы написать несколько строк, используя что-то вроде pyvips , а затем обработать их.
Например:
import sys
import pyvips
one = pyvips.Image.new_from_file(sys.argv[1])
two = pyvips.Image.new_from_file(sys.argv[2], access='sequential')
one.rot180().join(two, 'vertical').write_to_file(sys.argv[3])
Подсказка access=
наnew_from_file
в two
означает, что мы планируем прочитать второе изображение сверху вниз, т.е.в том же порядке, в котором пиксели появляются в файле jpg.Это позволит libvips транслировать это изображение, поэтому оно может перекрывать декодирование two
с записью выходного изображения.
На этом ноутбуке 2015 года я вижу:
$ vipsheader ~/pics/top.jpg ~/pics/bot.jpg
/home/john/pics/top.jpg: 16000x24000 uchar, 3 bands, srgb, jpegload
/home/john/pics/bot.jpg: 16000x24000 uchar, 3 bands, srgb, jpegload
$ /usr/bin/time -f %M:%e ./join.py ~/pics/top.jpg ~/pics/bot.jpg x.jpg
115236:27.85
$ vipsheader x.jpg
x.jpg: 16000x48000 uchar, 3 bands, srgb, jpegload
Итакпик 115 МБ памяти, и он работает в течение 28 секунд реального времени.
Это создаст временный файл для one
, чтобы он мог выполнять поворот.Если вы в порядке, используя много памяти, вы можете попробовать:
one = pyvips.Image.new_from_file(sys.argv[2], memory=True)
Это заставит libvips открываться через область памяти.Теперь я вижу:
$ /usr/bin/time -f %M:%e ./join.py ~/pics/top.jpg ~/pics/bot.jpg x.jpg
1216812:14.53
Только 15 секунд реального времени, но болезненное пиковое использование памяти в 1,2 ГБ.