Как ускорить сложную обработку изображений?

Каждый пользователь сможет загрузить 100 TIFF (черно-белые) изображения.

Процесс требует:

  1. Перерабатывать tif в jpg,

  2. Изменить размер изображения до хх.

  3. Обрезать изображение до 200 пикселей.

  4. Добавьте текстовый водяной знак.

Вот мой PHP-код:

move_uploaded_file($image_temp,$destination_folder.$image_name);

$image_name_only = strtolower($image_info["filename"]);

$name=$destination_folder.$image_name_only.".jpg";
$thumb=$destination_folder."thumb_".$image_name_only.".jpg";
$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$destination_folder.$image_name. ' '.$name.' 2>&1';
exec($exec, $exec_output, $exec_retval);

$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. ' -resize 1024x  '.$name;
exec($exec, $exec_output, $exec_retval);

$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. ' -thumbnail 200x200!  '.$thumb;
exec($exec, $exec_output, $exec_retval);

$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. "  -background White  label:ش.پ12355  -append  ".$name;
exec($exec, $exec_output, $exec_retval);

Этот код работает. Но среднее время обработки каждого изображения составляет 1 секунду.
Так что для 100 изображений это, вероятно, займет около 100 секунд.

Как я могу ускорить весь этот процесс (конвертировать, изменять размер, обрезать, водяные знаки)?

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

У меня есть сервер G8: Ram: 32G, процессор: Intel Xeon E5-2650 (4 процесса)

версия: ImageMagick 6.9.0-3 Q16 x64

ОСОБЕННОСТИ: OpenMP

convert logo: -resize 500% -bench 10 1.png

Performance[1]: 10i 0.770ips 1.000e 28.735u 0:12.992
Performance[2]: 10i 0.893ips 0.537e 26.848u 0:11.198
Performance[3]: 10i 0.851ips 0.525e 27.285u 0:11.756
Performance[4]: 10i 0.914ips 0.543e 26.489u 0:10.941
Performance[5]: 10i 0.967ips 0.557e 25.803u 0:10.341
Performance[6]: 10i 0.797ips 0.509e 27.737u 0:12.554
Performance[7]: 10i 0.963ips 0.556e 25.912u 0:10.389
Performance[8]: 10i 0.863ips 0.529e 26.707u 0:11.586

Пределы ресурса:

Ширина: 100MP; Высота: 100MP; Площадь: 17,16GP; Память: 7,9908 ГБ; Карта: 15,982 ГБ; Диск: без ограничений; Файл: 1536; Поток: 8; Дроссель: 0; Время: без ограничений

6

Решение

0. Два подхода

По сути, эта задача может быть решена двумя различными способами или комбинацией двух:

  1. Создайте свои команды как можно умнее.
  2. Обменяйте ускорение на потери качества.

В следующих нескольких разделах обсуждаются оба подхода.

1. Проверьте, какой у вас ImageMagick: «Q8», «Q16», «Q32» или «Q64»?

Сначала проверьте вашу точную версию ImageMagick и запустите:

convert -version

Если ваш ImageMagick имеет Q16 (или даже Q32 или же Q64, что возможно, но излишне!) в строке его версии:
Это означает, что все внутренние функции ImageMagick обрабатывают все изображения как имеющие 16-битную (или 32- или 64-битную) глубину канала.
Это дает вам лучшее качество при обработке изображений.
Но это также требует двойной памяти по сравнению с Q8,
Так что в то же время это означает снижение производительности.

Следовательно: вы можете проверить, каких преимуществ вы получите, переключившись на Q8-Build.
(The Q является символом для «квантовая глубина» поддерживается сборкой ImageMagick.)

Вы заплатите по возможности Q8прирост производительности с потерей качества, хотя.
Просто проверьте, с какой скоростью вы достигаете Q8 над Q16и какие потери качества вы терпите.
Затем решите, можете ли вы жить с недостатками или нет …

В любом случае Q16 будет использовать в два раза больше оперативной памяти для каждого изображения, и Q32 снова будет использовать в два раза больше Q16,
Это не зависит от фактических битов на пиксели, видимых во входных файлах.
16-битные файлы изображений при сохранении также будут занимать больше дискового пространства, чем 8-битные.

С Q16 или же Q32 требуя больше памяти, вы всегда должны убедиться, что вам этого достаточно.
Так как превышение Ваша физическая память была бы очень плохой новостью.
Если больше Q делает процесс подкачки на диск, производительность падает.
1074 x 768 пиксельное изображение (width x height) потребуется следующее количество виртуальной памяти, в зависимости от квантовой глубины:

Quantum                   Virtual Memory
Depth    (consumed by 1 image 1024x768)
-------    ------------------------------
8         3.840 kiB  (=~  3,75 MiB)
16         7.680 kiB  (=~  7,50 MiB)
32        15.360 kiB  (=~ 14,00 MiB)

Также имейте в виду, что некоторые «оптимизированные» конвейеры обработки (см. Ниже) должны будут хранить несколько копий изображения в виртуальной памяти!
Как только виртуальная память не может быть удовлетворена доступной оперативной памятью, система начнет подкачку и потребует «память» с диска.
В этом случае вся умная оптимизация конвейера команд, конечно, исчезла и начинает опускаться до самого обратного.

День рождения ImageMagick был в аере, когда процессоры могли обрабатывать только 1 бит за раз.
Это было десятилетия назад.
С тех пор архитектура процессора сильно изменилась.
16-битные операции раньше занимали вдвое больше, чем 8-битные операции, или даже дольше.
Затем появились 16-битные процессоры.
16-битные операции стали стандартными.
Процессоры были оптимизированы для 16-битных:
Внезапно некоторые 8-битные операции могут занять даже больше, чем 16-битные эквиваленты.

В настоящее время распространены 64-битные процессоры.
Итак Q8 против Q16 против Q32 Аргумент в реальных условиях может быть даже недействительным.
Кто знает?
Я не знаю каких-либо серьезных сравнений по этому поводу.
Было бы интересно, если бы кто-то (с действительно глубоким ноу-хау о процессорах и тестировании реальных программ) однажды запустил такой проект.

Да, я вижу, вы используете Q16 на винде.
Но я все еще хотел упомянуть об этом, для полноты картины …
В будущем другие пользователи будут читать этот вопрос и давать ответы.

Скорее всего, так как ваши входные TIFFs только черный + белый, качество изображения на выходе Q8 build будет достаточно для вашего рабочего процесса.
(Я просто не знаю, будет ли это также значительно быстрее:
это в значительной степени также зависит от аппаратных ресурсов, на которых вы запускаете это …)

Кроме того, если ваша установка спортивная поддержка HDRI (изображения с высоким динамическим разрешением), это также может привести к некоторому снижению скорости.
Кто знает?
Итак, построение IM с настройкой параметров --disable-hdri --quantum-depth 8 может или не может привести к улучшению скорости.
Никто никогда не проверял это серьезно …
Единственное, что мы знаем об этом:
эти параметры уменьшат качество изображения.
Однако большинство людей даже не заметят этого, если только они не примут действительно пристальные взгляды и не сделают прямое сравнение изображение за изображением …

 

2. Проверьте возможности вашего ImageMagick

Затем проверьте, поставляется ли с вашей установкой ImageMagick OpenCL и / или OpenMP служба поддержки:

convert -list configure | grep FEATURES

Если это так (как у меня), вы должны увидеть что-то вроде этого:

FEATURES      DPC HDRI OpenCL OpenMP Modules

OpenCL (для С omputing L anguage) использует ImageMagick’s параллельные вычисления особенности (если они включены).
Это будет использовать графический процессор вашего компьютера в дополнение к процессору для операций обработки изображений.

OpenMP (для M в конечномп обрабатывает) делает что-то похожее:
это позволяет ImageMagick работать параллельно на всех ядрах вашей системы.
Таким образом, если у вас четырехъядерная система и вы изменяете размер изображения, изменение размера происходит на 4 ядрах (или даже на 8, если у вас есть гиперпоточность).

Команда

convert -version

печатает некоторую основную информацию о поддерживаемых функциях.
Если доступны OpenCL / OpenMP, вы увидите один из них (или оба) в выходных данных.

Если ни один из двух не появляется:
Изучите самую последнюю версию ImageMagick, в которой скомпилирована поддержка OpenCL и / или OpenMP.

Если вы собираете пакет самостоятельно из исходников, убедитесь, что используются OpenCL / OpenMP.
Сделайте это, включив соответствующие параметры в ваш шаг настройки:

./configure  [...other options-]  --enable-openmp  --enable-opencl

Документация ImageMagick об OpenMP и OpenCL находится здесь:

  • Параллельное выполнение с OpenMP.
    Прочитайте это внимательно.
    Потому что OpenMP не является серебряной пулей, и он не работает при любых обстоятельствах …
  • Параллельное выполнение с OpenCL.
    Здесь применимо то же, что и выше.
    Кроме того, не все операции ImageMagick поддерживают OpenCL.
    По ссылке здесь есть список тех, которые есть.
    -resize это один из них.

Советы и инструкции по сборке ImageMagick из исходных кодов и настройке сборки, поясняющие различные варианты, находятся здесь:

Эта страница также включает в себя краткое обсуждение --with-quantum-depth настроить вариант.

3. Оцените ваш ImageMagick

Теперь вы также можете использовать встроенный -bench возможность заставить ImageMagick запустить тест для вашей команды.
Например:

convert logo: -resize 500% -bench 10 logo.png

[....]
Performance[4]: 10i 1.489ips 1.000e 6.420u 0:06.510

Над командой с -resize 500% говорит ImageMagick запустить convert командуйте и масштабируйте встроенный IM logo: изображение на 500% в каждом направлении.
-bench 10 part сообщает ему, что нужно выполнить ту же команду 10 раз в цикле, а затем вывести результаты производительности:

  • Так как у меня включен OpenMP, у меня есть 4 темы (Performance[4]:).
  • Он сообщает, что он выполнил 10 итераций (10i).
  • Скорость была почти 1,5 итераций в секунду (1.489ips).
  • Общее время, отведенное пользователем, составило 6,420 секунд.

Если ваш результат включает Performance[1]:и только одна строка, значит, в вашей системе не включен OpenMP.
(Вы может быть в состоянии включить его, если ваша сборка его поддерживает: run convert -limit thread 2.)

4. Настройте ограничения ресурсов вашего ImageMagick

Узнайте, как ImageMagick вашей системы настроен в отношении пределы ресурса.
Используйте эту команду:

определить список ресурсов
Файловая область Карта памяти Время резьбы диска
-------------------------------------------------- ------------------
384 8.590GB 4GiB 8GiB без ограничений 4 без ограничений

Выше показаны настройки моей текущей системы (не значения по умолчанию — я настраивал их в прошлом).
Числа являются максимальным количеством каждого ресурса, который будет использовать ImageMagick.
Вы можете использовать каждое из ключевых слов в заголовках столбцов, чтобы увеличить вашу систему.
Для этого используйте convert -limit <resource> <number> в задавать это к новому пределу.

Может быть ваш Результат выглядит примерно так:

определить список ресурсов
Файловая область Карта памяти Время резьбы диска
-------------------------------------------------- ------------------
192 4.295GB 2GiB 4GiB без ограничений 1 без ограничений
  • files определяет максимальное количество одновременно открытых файлов, которые может использовать ImageMagick.
  • memory, map, area а также disk пределы ресурса определены в байтах.
    За установка их к различным значениям вы можете использовать префиксы SI, например, 500 МБ).

Когда ты делать есть OpenMP для ImageMagick в вашей системе, вы можете запустить.

convert -limit thread 2

Это позволяет 2 параллельных потока в качестве первого шага.
Затем снова запустите тест и посмотрите, действительно ли он имеет значение, и если да, то насколько.
После этого вы можете установить ограничение на 4 или даже 8 и повторить упражнение ….

5. Используйте Magick Pixel Cache (MPC) и / или Magick Persistent Registry (MPR).

в заключение, Вы можете поэкспериментировать со специальным внутренним форматом пиксельного кэша ImageMagick.
Этот формат называется MPC (Magick Pixel Cache).
Он существует только в памяти.

Когда создается MPC, обработанное входное изображение сохраняется в ОЗУ в виде несжатого растрового формата.
Таким образом, в основном, MPC является родным в памяти Несжатый формат файла ImageMagick.
Это просто прямой дамп памяти на диск.
Чтение — это быстрая карта памяти с диска в память по мере необходимости (аналогично перестановке страниц памяти).
Но никакого декодирования изображения не требуется.

(Более технические детали: MPC как формат не является переносимым.
Это также не подходит как долгосрочный формат архива.
Его единственная пригодность в качестве промежуточного формата для высокопроизводительной обработки изображений.
Для поддержки одного изображения требуется два файла.)

Если вы все еще хотите сохранить этот формат на диск, учтите следующее:

  • Образ атрибуты записываются в файл с расширением .MPC.
  • Образ пикселей записываются в файл с расширением .кэш.

Его главное преимущество ощущается, когда …

  1. …обработка очень больших изображений, или когда
  2. …применяя несколько операций к одному и тому же изображению в «эксплуатационные трубопроводы».

MPC был разработан специально для шаблонов рабочих процессов, которые соответствуют критериям «читать много раз, писать один раз».

Некоторые люди говорят, что для таких операций производительность улучшается, но у меня нет личного опыта с этим.

Сначала преобразуйте свою базовую картинку в MPC:

convert input.jpeg input.mpc

и только потом запустить

convert input.mpc [...your long-long-long list of crops and operations...]

Тогда посмотрите, значительно ли это сэкономит вам время.

Скорее всего, вы можете использовать этот формат MPC даже «встроенный» (с помощью специального mpc: обозначения, см. ниже).

Формат MPR (постоянный регистр памяти) делает что-то подобное.
Он считывает изображение в именованный регистр памяти.
Ваш процессный конвейер также может снова прочитать изображение из этого регистра, если ему потребуется многократный доступ к нему.
Изображение сохраняется в регистре, из которого выходит текущий конвейер команд.

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

6. Построить подходящий конвейер обработки мгновенных сообщений для выполнения всех задач за один раз.

Как вы описываете свой процесс, он состоит из 4 этапов:

  1. Конвертировать TIFF в JPEG.
  2. Изменить размер изображения JPEG до хх (какое значение ??)
  3. Обрезать JPEG до 200 пикселей.
  4. Добавьте текстовый водяной знак.

Пожалуйста, скажите, правильно ли я понимаю ваши намерения при чтении фрагментов кода:

  • У вас есть 1 входной файл, TIFF.
  • Вы хотите 2 конечных выходных файла:
    1. 1 миниатюра JPEG, размером 200х200 пикселей;
    2. 1 с меткой JPEG, шириной 1024 пикселя (соотношение сторон по высоте при вводе TIFF);
    3. 1 (без метки) JPEG — это только промежуточный файл, который вы не хотите хранить.

По сути, каждый шаг использует свою собственную команду — всего 4 разные команды.
Это можно значительно ускорить, используя один командный конвейер, который выполняет все шаги самостоятельно.

Более того, вам, кажется, на самом деле не нужно держать конечный результат — немаркированный JPEG — и все же ваша единственная команда для его создания в качестве промежуточного временного файла сохраняет его на диск. Тогда мы можем попытаться вообще пропустить этот шаг и попытаться достичь конечного результата без дополнительной записи на диск.

Существуют разные подходы к этому изменению.
Я покажу вам (и другим читателям) только один — и только для CLI, а не для PHP.
Я не парень по PHP — ваша собственная задача — «преобразовать» мой метод CLI в соответствующие вызовы PHP.

(Но во что бы то ни стало: пожалуйста, сначала протестируйте мои команды, действительно используя CLI, чтобы увидеть, стоит ли усилий при переводе подхода на PHP!)

Но, пожалуйста, сначала убедитесь, что вы действительно понять архитектуру и структуру более сложных командных строк ImageMagick!
Для этой цели, пожалуйста, обратитесь к этому другой мой ответ:

Ваши 4 шага переводятся в следующие отдельные команды ImageMagick:

convert image.tiff image.jpg

convert image.jpg -resize 1024x image-1024.jpg

convert image-1024.jpg -thumbnail 200x200 image-thumb.jpg

convert -background white image-1024.jpg label:12345 -append image-labelled.jpg

Теперь, чтобы преобразовать этот рабочий процесс в одну команду конвейера …
Следующая команда делает это.
Он должен выполняться быстрее (независимо от того, каковы ваши результаты при выполнении моих вышеуказанных шагов 0 .— 4.):

convert image.tiff                                                             \
-respect-parentheses                                                          \
+write mpr:XY                                                                 \
\( mpr:XY                                       +write image-1024.jpg \)     \
\( mpr:XY -thumbnail 200x200                    +write image-thumb.jpg \)    \
\( mpr:XY -background white label:12345 -append +write image-labelled.jpg \) \
null:

Пояснения:

  • -respect-parentheses :
    требуется действительно сделать независимы друг от друга подкоманды, выполняемые внутри \( .... \) скобки.
  • +write mpr:XY :
    используется для записи входного файла в регистр памяти MPR.
    XY это просто метка (вы можете использовать все что угодно), необходимая для последующего повторного вызова того же изображения.
  • +write image-1024.jpg :
    записывает результат подкоманды, выполненной в первой паре скобок, на диск.
  • +write image-thumb.jpg :
    записывает результат подкоманды, выполненной во второй паре скобок, на диск.
  • +write image-labelled.jpg :
    записывает результат подкоманды, выполненной в третьей паре скобок, на диск.
  • null: :
    завершает командный конвейер.
    Требуется, потому что иначе мы бы заканчивали закрывающей скобкой последней подкоманды.

7. Сравнительный анализ 4 отдельных команд и одного конвейера

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

Первая запускает последовательность из 4 отдельных команд 100 раз (и сохраняет все полученные изображения под разными именами файлов).

time for i in $(seq -w 1 100); do
convert image.tiff                                                          \
image-indiv-run-${i}.jpg
convert image-indiv-run-${i}.jpg -sample 1024x                              \
image-1024-indiv-run-${i}.jpg
convert image-1024-indiv-run-${i}.jpg -thumbnail 200x200                    \
image-thumb-indiv-run-${i}.jpg
convert -background white image-1024-indiv-run-${i}.jpg label:12345 -append \
image-labelled-indiv-run-${i}.jpg
echo "DONE: run indiv $i ..."done

Мой результат за 4 отдельные команды (повторяется 100 раз!) это так:

real  0m49.165s
user  0m39.004s
sys   0m6.661s

Вторая команда умножает один конвейер:

time for i in $(seq -w 1 100); do
convert image.tiff                                        \
-respect-parentheses                                     \
+write mpr:XY                                            \
\( mpr:XY -resize 1024x                                 \
+write image-1024-pipel-run-${i}.jpg     \)   \
\( mpr:XY -thumbnail 200x200                            \
+write image-thumb-pipel-run-${i}.jpg    \)   \
\( mpr:XY -resize 1024x                                 \
-background white label:12345 -append         \
+write image-labelled-pipel-run-${i}.jpg \)   \
null:
echo "DONE: run pipeline $i ..."done

Результат для один трубопровод (повторяется 100 раз!) это так:

real   0m29.128s
user   0m28.450s
sys    0m2.897s

Как видите, один конвейер работает примерно на 40% быстрее, чем 4 отдельные команды!

Теперь вы также можете инвестировать в многопроцессорность, большой объем оперативной памяти, быстрое аппаратное обеспечение SSD, чтобы ускорить процесс 🙂

Но сначала переведите этот подход CLI в код PHP …


Есть еще несколько вещей, которые можно сказать по этой теме.
Но мое время истекает.
Я, вероятно, вернусь к этому ответу через несколько дней и обновлю его еще немного …


Обновить: Мне пришлось обновить этот ответ с новыми номерами для сравнительного анализа:
Первоначально я забыл включить -resize 1024x операция (глупый я!) в конвейерную версию.
Включив его, прирост производительности все еще есть, но уже не такой большой.


8. Используйте -clone 0 скопировать изображение в память

Вот еще одна альтернатива, чтобы попробовать вместо mpr: подход с именованным регистром памяти, как предложено выше.

Он использует (опять же в «стороне обработки внутри скобок») -clone 0 операция.
Вот как это работает:

  1. convert читает входной TIFF с диска один раз и загружает его в память.
  2. каждый -clone 0 Оператор делает копию первого загруженного изображения (потому что оно имеет индекс 0 в текущем стеке изображений).
  3. Каждый вложенный конвейер «в скобках» всего конвейера команд выполняет некоторую операцию с клоном.
  4. каждый +write операция сохраняет соответствующий результат на диск.

Так вот команда для сравнения этого:

time for i in $(seq -w 1 100); do
convert image.tiff                                         \
-respect-parentheses                                      \
\( -clone 0 -thumbnail 200x200                           \
+write image-thumb-pipel-run-${i}.jpg    \)  \
\( -clone 0 -resize 1024x                                \
-background white label:12345 -append        \
+write image-labelled-pipel-run-${i}.jpg \)  \
null:
echo "DONE: run pipeline $i ..."done

Мой результат:

real   0m19.432s
user   0m18.214s
sys    0m1.897s

К моему удивлению, это быстрее, чем версия, которая использовала mpr: !

9. Используйте -scale или же -sample вместо -resize

Эта альтернатива, скорее всего, ускорит вашу подоперацию изменения размера.
Но это, вероятно, приведет к несколько худшему качеству изображения (вам нужно будет проверить, заметна ли эта разница).

Для получения дополнительной информации о разнице между -resize, -sample а также -scale см. следующий ответ:

Я тоже это попробовал:

time for i in $(seq -w 1 100); do
convert image.tiff                                         \
-respect-parentheses                                      \
\( -clone 0 -thumbnail 200x200                           \
+write image-thumb-pipel-run-${i}.jpg    \)  \
\( -clone 0 -scale 1024x                                 \
-background white label:12345 -append        \
+write image-labelled-pipel-run-${i}.jpg \)  \
null:
echo "DONE: run pipeline $i ..."done

Мой результат:

real   0m16.551s
user   0m16.124s
sys    0m1.567s

Это самый быстрый результат (я объединил его с +clone вариант).

Конечно, эта модификация также может быть применена к вашему начальному методу, выполняющему 4 разные команды.

10. Подражать Q8 построить, добавив -depth 8 к командам.

Я на самом деле не запускал и не измерял это, но полная команда была бы.

time for i in $(seq -w 1 100); do
convert image.tiff                                            \
-respect-parentheses                                         \
\( -clone 0 -thumbnail 200x200 -depth 8                     \
+write d08-image-thumb-pipel-run-${i}.jpg    \) \
\( -clone 0 -scale 1024x       -depth 8                     \
-background white label:12345 -append           \
+write d08-image-labelled-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."done

Эта модификация также применима к вашему первоначальному методу «Я запускаю 4 разные команды».

11. Объедините это с GNU parallelв соответствии с предложением Марка Сетчелла

Это, конечно, применимо и целесообразно для вас, только если ваш общий рабочий процесс допускает такое распараллеливание.

Для моего маленького теста это применимо.
Для вашего веб-сервиса может быть так, что вы знаете только одну работу за раз …

time for i in $(seq -w 1 100); do                                 \
cat <<EOF
convert image.tiff                                            \
\( -clone 0 -scale  1024x         -depth 8                  \
-background white label:12345 -append           \
+write d08-image-labelled-pipel-run-${i}.jpg \) \
\( -clone 0 -thumbnail 200x200  -depth 8                    \
+write d08-image-thumb-pipel-run-${i}.jpg   \)  \
null:
echo "DONE: run pipeline $i ..."EOF
done | parallel --will-cite

Результаты:

real  0m6.806s
user  0m37.582s
sys   0m6.642s

Кажущееся противоречие между user а также real Время можно объяснить:
user время представляет собой сумму всех тактов времени, которые были синхронизированы на 8 разных ядрах процессора.

С точки зрения пользователя, смотрящего на часы, это было намного быстрее: менее 10 секунд.

12. Резюме

Выберите свои предпочтения — комбинируйте разные методы:

  1. Некоторое ускорение может быть достигнуто (с таким же качеством изображения, как в настоящее время) построение более умного командного конвейера.
    Избегайте выполнения различных команд (где каждый convert приводит к новому процессу, и должен прочитать его вход с диска).
    Упакуйте все манипуляции с изображениями в один процесс.
    Используйте «обработку сторон в скобках».
    Использовать -clone или же mbr: или же mbc: или даже объединить каждый из них.

  2. Некоторые ускорения могут быть дополнительно получены качество торгового изображения с производительностью:
    Некоторые из ваших вариантов:

    1. -depth 8 (должен быть объявлен в системе ОП) против -depth 16 (по умолчанию в системе ОП)
    2. -resize 1024 против -sample 1024x против -scale 1024x
  3. Используйте GNU parallel если ваш рабочий процесс позволяет это.

33

Другие решения

Как всегда, @KurtPfeifle предоставил превосходно аргументированный и объясненный ответ, и все, что он говорит, является твердым советом, который вы бы хорошо выслушали и внимательно следили.

Хотя можно сделать немного больше, но это больше, чем я могу добавить в качестве комментария, поэтому я добавляю его в качестве другого ответа, хотя это только улучшение Курта …

Я не знаю, какой размер изображения для импульса использовал Курт, поэтому я сделал одно из 3000×2000 и сравнил мои времена выполнения с его, чтобы увидеть, были ли они сопоставимы, так как у нас другое оборудование. Отдельные команды выполнялись на моей машине за 42 секунды, а конвейерные — за 36 секунд, поэтому я думаю, что размер моего изображения и аппаратные средства в целом схожи.

Затем я использовал GNU Parallel для параллельного выполнения заданий — думаю, вы получите большую выгоду от этого на Xeon. Вот что я сделал …

time for i in $(seq -w 1 100); do
cat <<EOF
convert image.tiff                                        \
-respect-parentheses                                     \
+write mpr:XY                                            \
\( mpr:XY -resize 1024x                                 \
+write image-1024-pipel-run-${i}.jpg     \)   \
\( mpr:XY -thumbnail 200x200                            \
+write image-thumb-pipel-run-${i}.jpg    \)   \
\( mpr:XY -background white label:12345 -append         \
+write image-labelled-pipel-run-${i}.jpg \)   \
null:
echo "DONE: run pipeline $i ..."EOF
done | parallel

Как вы можете видеть, все, что я делал, это выводил команды, которые нужно запустить на стандартный вывод, и передавал их в GNU Parallel. Запустите этот путь, это займет всего 10 секунд на моей машине.

Я также попытался имитировать функциональность с помощью ffmpegи придумал это, что на моих тестовых изображениях выглядит довольно похоже — ваш пробег может отличаться.

#!/bin/bash
for i in $(seq -w 1 100); do
echo ffmpeg -y -loglevel panic -i image.tif ff-$i.jpg
echo ffmpeg -y -loglevel panic -i image.tif -vf scale=1024:682 ff-$i-1024.jpg
echo ffmpeg -y -loglevel panic -i image.tif -vf scale=200:200 ff-$i-200.jpg
done | parallel

Это выполняется за 7 секунд на моем iMac с входным файлом image.tif размером 3000×2000.

Я с треском провалился libturbo-jpeg установлен с ImageMagick под homebrew,

4

Я продолжаю слышать от некоторых людей, что GraphicsMagick (разветвление, созданное несколько лет назад, ответвление от ImageMagick) значительно быстрее, чем ImageMagick.

Так что я воспользовался этой возможностью, чтобы дать ему вращение. Отсюда мой второй ответ.

Я выполнил следующий цикл из 4 отдельных gm команды. Это делает результаты сопоставимыми с 4 отдельными convert Команды документированы в моем другом ответе. Это случилось на той же машине:

time for i in $(seq -w 1 100); do
gm convert         image.tiff                         gm-${i}-image.jpg
gm convert gm-${i}-image.jpg      -resize 1024x       gm-${i}-image-1024.jpg
gm convert gm-${i}-image-1024.jpg -thumbnail 200x200  gm-${i}-image-thumb.jpg
gm convert -background white    \
gm-${i}-image-1024.jpg label:12345 -append gm-${i}-image-labelled.jpg
echo "GraphicsMagick run no. $i ..."done

Результирующие времена:

real   1m4.225s
user   0m51.577s
sys    0m8.247s

Это означает: для этой конкретной работы, и на этой машине мой Q8 GraphicsMagick (версия 1.3.20 2014-08-16 Q8) медленнее с 64 секунды нужно, чем мой Q16 ImageMagick (версия 6.9.0-0 Q16 x86_64 2014-12-06), который нужен 50 секунд на 100 трасс каждый.


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

Вы можете спросить: Что еще делала эта машина и ее ОС при проведении каждого теста? Какие другие приложения были загружены в память одновременно? и т. д., и вы правы. — Но теперь вы можете запускать свои собственные тесты. Одна вещь, которую вы можете сделать, чтобы обеспечить почти одинаковые условия для обоих тестов: запустить их одновременно в 2 разных оконных окнах!)

3

Я не мог устоять перед попыткой этого теста с VIPs. Я использовал эти два сценария:

#!/bin/bash

for file in $*; do
convert $file \
-respect-parentheses \
\( -clone 0 -resize 200x200 \
+write $file-thumb.jpg \)  \
\( -clone 0 -resize 1024x \
-background white label:12345 -append \
+write $file-labelled.jpg \) \
null:
done

и vips с использованием интерфейса Python:

#!/usr/bin/python

import sys
from gi.repository import Vips

for filename in sys.argv[1:]:
im = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL)

im = im.resize(1024.0 / im.width)
mem = Vips.Image.new_memory()
im.write(mem)

thumb = mem.resize(200.0 / mem.width)
thumb.write_to_file(filename + "-thumb.jpg")

txt = Vips.Image.text("12345", dpi = 72)
footer = txt.embed(10, 10, mem.width, txt.height + 20)
mem = mem.join(footer, "vertical")

mem.write_to_file(filename + "-labelled.jpg")

Затем на 100 3000 x 2000 изображений RGB TIFF с IM 6.8.9-9 и vips 8.0, оба с libjpeg-turbo, я вижу:

$ time ../im-bench.sh *
real    0m32.033s
user    1m40.416s
sys 0m3.316s
$ time ../vips-bench.py *
real    0m22.559s
user    1m8.128s
sys 0m1.304s
1