изменение размера изображения с помощью imagemagick через скрипт оболочки - PullRequest
0 голосов
/ 03 июня 2010

Я не очень много знаю о bash-сценариях ИЛИ imagemagick, но я пытаюсь создать сценарий, в котором вы можете задать своего рода шаблон соответствия регулярному выражению для списка изображений, а затем обработать их в новые файлы заданный префикс имени файла.

например, с учетом следующего каталога dir:

allfiles01.jpg allfiles02.jpg allfiles03.jpg

я бы хотел назвать скрипт так:

./resisemany.sh allfiles*.jpg 30 newnames*.jpg

конечным результатом этого будет то, что вы получите кучу новых файлов с новыми именами, числа совпадают,

пока что у меня есть:

IMAGELIST=$1
RESIEZFACTOR=$2
NUMIMGS=length($IMAGELIST)

for(i=0; i<NUMIMGS; i++)
  convert $IMAGELIST[i] -filter bessel -resize . RESIZEFACTOR . % myfile.JPG

Спасибо за любую помощь ... Части, с которыми мне, очевидно, нужна помощь: 1. как определить критерии соответствия bash-скрипта, которые он понимает 2. как использовать $ 2 без совпадения со вторым элементом в списке изображений 3. как получить длину списка изображений 4. как создать правильный цикл for в таком случае 5. как правильно заменить текст для команды оболочки, с помощью которой вы добавляете элементы, на которые я намекаю.

JML

Ответы [ 3 ]

6 голосов
/ 03 июня 2010

Вероятно, стандартная программа будет работать так: взять шаблон имени файла «in» и шаблон имени файла «out» и выполнить операцию с каждым файлом в текущем каталоге, который соответствует шаблону «in», заменив соответствующие части. в "Out" шаблон. Это довольно легко, если у вас есть жестко запрограммированный шаблон, когда вы можете написать одноразовые команды, такие как

for infile in *.jpg; do convert $infile -filter bessel -resize 30% ${infile//allfiles/newnames}; done

Однако, чтобы создать скрипт, который будет делать это с любым шаблоном, вам нужно что-то более сложное, потому что преобразование вашего имени файла может быть чем-то более сложным, чем просто замена одной части другой. К сожалению, Bash на самом деле не дает вам способа определить, какая часть имени файла соответствует определенной части шаблона, поэтому вам придется использовать более мощный механизм регулярных выражений, такой как sed, например:

#!/bin/bash

inpattern=$1
factor=$2
outpattern=$3
for infile in *; do
    outfile=$(echo $infile | sed -n "s/$inpattern/$outpattern/p")
    test -z $outfile && continue
    convert $infile -filter bessel -resize $factor% $outfile
done

Это может быть вызвано как

./resizemany.sh 'allfiles\(.*\).jpg' 30 'newnames\1.jpg'

. , (Это не так уж плохо, на самом деле)

5 голосов
/ 03 июня 2010

Вы можете устранить проблему с регулярным выражением, если создадите папку со всеми обрабатываемыми файлами, а затем запустите что-то вроде:

for img in `ls *.jpg`
do
  convert $img -filter bessel -resize 30% processed-$img
done

Тогда, если вам понадобится переименовать их позже, вы можете сделать что-то вроде:

ls | nl -nrz -w2 | while read a b;  do mv "$b" newfilename.$a.jpg; done;

Кроме того, если вы выполняете пакетный процесс той же операции, вы можете увидеть, может ли помочь использование mogrify (метод imagemagik для конвертации нескольких файлов). Как и в приведенном выше примере, всегда хорошо сделать копию папки, а затем запустить любую обработку, чтобы не уничтожить исходные файлы.

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

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

./resizemany.sh -r 30 -n newnames -o allfiles allfiles*.jpg

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

Выходные файлы будут именоваться с использованием сценария rename, часто встречающегося в системах с установленным Perl. Файл с именем "allfiles03.jpg" будет выведен как "newname03.jpg".

#!/bin/bash

options=":r:n:o:"
while getopts $options option
do
    case $option in
        n)
            newnamepattern=$OPTARG
            ;;
        o)
            oldnamepattern=$OPTARG
            ;;
        r)
            resizefacor=$OPTARG
            ;;

        \?)
            echo "Invalid option"
            exit 1
    esac
done
# a check to see if any options are missing should be performed (not implemented)
shift $((OPTIND - 1))
# now all that's left will be treated as filenames
for file
do
    convert (input options) "$file" -resize $resizefactor (output options) "${file}.out" 
    rename "s/$old/$new/;s/\.out$//" "${file}.out"
done

Это не проверено (очевидно, поскольку большинство аргументов convert отсутствуют).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...