Я сделал несколько изображений и провел несколько тестов, чтобы вы могли увидеть влияние различных методов на производительность.
Я сделал изображения, содержащие случайные, трудно сжимаемые данные с размерами и размерами файлов, которые соответствуют вашим, т.е.
convert -size 8000x6000 xc:gray +noise random -quality 35 image.jpg
затем ls
дает 13 МБ следующим образом:
-rw-r--r-- 1 mark staff 13M 23 Aug 17:55 image.jpg
Я сделал 128 таких случайных изображений, потому что это хорошо кратно 8 ядрам процессора на моей машине — см. параллельные тесты позже.
Теперь о методах...
Способ 1
Это наивный метод — вы просто создаете все файлы, которые вы просили, один за другим.
#!/bin/bash
for f in image*jpg; do
for w in 3000 2000 1000 500 250 100; do
convert $f -resize ${w}x res_${f}_${w}.jpg
done
done
Время: 26 минут 46 секунд
Метод 2
Здесь мы читаем каждое изображение только один раз, но генерируем все выходные размеры из одного входного изображения, и это значительно быстрее.
#!/bin/bash
for f in image*jpg; do
convert $f -resize 3000x -write res_${f}_3000.jpg \
-resize 2000x -write res_${f}_2000.jpg \
-resize 1000x -write res_${f}_1000.jpg \
-resize 500x -write res_${f}_500.jpg \
-resize 250x -write res_${f}_250.jpg \
-resize 100x res_${f}_100.jpg
done
Время: 6 мин. 17 сек.
Способ 3
Здесь мы заранее сообщаем ImageMagick, что самое большое изображение, которое нам понадобится, составляет всего 3000x2250 пикселей, поэтому оно может использовать меньше памяти, считывать меньше уровней DCT и выполнять меньше операций ввода-вывода. Это называется «усадка при загрузке».
#!/bin/bash
for f in image*jpg; do
convert -define jpeg:size=3000x2250 $f \
-resize 3000x -write res_${f}_3000.jpg \
-resize 2000x -write res_${f}_2000.jpg \
-resize 1000x -write res_${f}_1000.jpg \
-resize 500x -write res_${f}_500.jpg \
-resize 250x -write res_${f}_250.jpg \
-resize 100x res_${f}_100.jpg
done
Время: 3 мин. 37 сек.
Кроме того, чтобы продемонстрировать сокращение времени, ввода-вывода и памяти, необходимых, когда вы заранее сообщаете ImageMagick, насколько большой вам понадобится образ, сравните эти две команды, обе из которых считывают один из ваших 8000x6000, 13 МБ. изображения, и оба генерируют одну и ту же миниатюру:
/usr/bin/time -l convert image.jpg -resize 500x result.jpg 2>&1 | egrep "resident|real"
1.92 real 1.77 user 0.14 sys
415727616 maximum resident set size
т.е. 415 МБ и 2 секунды
/usr/bin/time -l convert -define jpeg:size=500x500 image.jpg -resize 500x result.jpg 2>&1 | egrep "resident|real"
0.24 real 0.23 user 0.01 sys
23592960 maximum resident set size
т.е. 23 МБ и 0,2 секунды - и выходное изображение имеет такое же содержание и качество.
Метод 4
Здесь мы делаем все возможное и используем GNU Parallel, а также все вышеперечисленные методы, чтобы свести ваш процессор, вентиляторы и энергопотребление с ума!!!
#!/bin/bash
for f in image*jpg; do
cat<<EOF
convert -define jpeg:size=3000x2250 $f \
-resize 3000x -write res_${f}_3000.jpg \
-resize 2000x -write res_${f}_2000.jpg \
-resize 1000x -write res_${f}_1000.jpg \
-resize 500x -write res_${f}_500.jpg \
-resize 250x -write res_${f}_250.jpg \
-resize 100x res_${f}_100.jpg
EOF
done | parallel
Время: 56 секунд
Таким образом, мы можем сократить время обработки с 27 минут до 56 секунд, избегая ненужного чтения изображения и выполняя как можно больше выходных данных для каждого ввода, заранее сообщая ImageMagick, какую часть входного изображения ему нужно прочитать, и используя GNU. Параллельно, чтобы все ваши любимые ядра процессора были заняты. ХТН.
person
Mark Setchell
schedule
23.08.2015
JPEG
илиTIFF
или что-то в этом роде? А какой будет неровный файл? - person Mark Setchell   schedule 22.08.2015