Как обрезать север и центр с помощью Morgify в ImageMagick
Есть ли способ обрезать изображение по центру по горизонтали, а не по вертикали? Например, вот как я хотел бы обрезать изображение:
Однако, используя команду mogrify -crop 250x250 -gravity North cat.jpg
, Я получил:
Обратите внимание, что я собираюсь делать это в пакете с около 10000 изображений разных размеров, поэтому я не могу явно выбрать точную область для обрезки.
2 ответа
Вне моей головы, математически вы должны иметь дело с координатами, которые начинаются сверху слева 0,0
(Ака: NorthWest
в терминологии ImageMagick), поэтому вы можете расположить область рамки кадрирования примерно так:
(width of image - width of crop area) / 2
Таким образом, вы могли бы концептуально сделать что-то подобное на своем примере mogrify
команда:
mogrify -crop 250x250+[(width of image - 250)/2]+0 -gravity NorthWest cat.jpg
Это довольно хорошая концепция, но не полезная реальность. Но я просто немного поэкспериментировал и заставил это работать для одного тестового изображения:
CROP_W=250
CROP_H=250
IMG_W=$(identify -format %w test.jpg)
X_OFFSET=$((($IMG_W-$CROP_W)/2))
mogrify -crop ${CROP_W}x${CROP_H}+${X_OFFSET}+0 -gravity NorthWest test.jpg
Так как ImageMagick's -gravity
по умолчанию NorthWest
в любом случае, вы можете упростить это, удалив -gravity
вариант вообще так:
CROP_W=250
CROP_H=250
IMG_W=$(identify -format %w test.jpg)
X_OFFSET=$((($IMG_W-$CROP_W)/2))
mogrify -crop ${CROP_W}x${CROP_H}+${X_OFFSET}+0 test.jpg
И после тестирования этой концепции, я создал этот сценарий Bash, и он работает, как и ожидалось. Просто измените DIRECTORY
значение, соответствующее фактическому каталогу, в котором вы планируете действовать. И это echo mogrify
позволяет точно увидеть, что будет, если команда будет запущена; удалить это echo
и затем позволить сценарию пойти на это, если вы довольны результатами:
#!/bin/bash
# Set the crop width and height.
CROP_W=250
CROP_H=250
# Set the directory to act on.
DIRECTORY='/path/to/images'
# Use find to find all of the images; in this case JPEG images.
find ${DIRECTORY} -type f \( -name "*.jpg" -o -name "*.JPG" \) |\
while read FULL_IMAGE_PATH
do
# Get the image width with identify.
IMG_W=$(identify -format %w ${FULL_IMAGE_PATH})
# Calculate the X offset for the crop.
X_OFFSET=$((($IMG_W-$CROP_W)/2))
# Run the actual mogrify command.
# mogrify -crop ${CROP_W}x${CROP_H}+${X_OFFSET}+0 ${FULL_IMAGE_PATH}
echo mogrify -crop ${CROP_W}x${CROP_H}+${X_OFFSET}+0 ${FULL_IMAGE_PATH}
done
JakeGould дал рабочее решение, но я думаю, что гораздо более простым решением является не сценарий, а двухступенчатое преобразование. Сначала уменьшите высоту до 250 пикселей с северной гравитацией, затем уменьшите ширину до 250 пикселей с центральной гравитацией:
mogrify -gravity North -crop x250+0+0 cat.jpg
mogrify -gravity Center -crop 250x250+0+0 cat.jpg
В качестве альтернативы вы можете использовать конвертирование с промежуточным изображением, отличным от jpg, чтобы предотвратить потерю качества из-за дополнительного преобразования в jpg:
convert -gravity North -crop x250+0+0 cat.jpg png:- | convert -gravity Center -crop 250x250+0+0 png:- cat.jpg