3

Есть ли способ обрезать изображение по центру по горизонтали, а не по вертикали? Например, вот как я хотел бы обрезать изображение:

ожидаемый

Однако, используя команду mogrify -crop 250x250 -gravity North cat.jpg , я получаю:

gotted

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

2 ответа2

1

Вверху моей головы, математически вы должны иметь дело с координатами, которые начинаются с верхнего левого 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 -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
1

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .