Como cortar o norte e centralizar com morgify no ImageMagick

2

Existe uma maneira de cortar uma imagem centralizada horizontalmente, mas não centralizada verticalmente? Por exemplo, aqui está como eu gostaria de uma imagem cortada:

Noentanto,usandoocomandomogrify-crop250x250-gravityNorthcat.jpg,recebo:

Observação vou fazer isso em lote com cerca de 10.000 imagens de tamanhos diferentes, por isso não posso escolher explicitamente uma região exata para recortar.

    
por Steven Jeffries 19.10.2015 / 02:13

2 respostas

1

Na parte superior da minha cabeça, matematicamente você deve estar lidando com coordenadas que estão começando no canto superior esquerdo 0,0 (aka: NorthWest na terminologia do ImageMagick) então você gostaria de posicionar a área da caixa de corte para ser algo assim:

(width of image - width of crop area) / 2

Assim, você poderia conceitualmente fazer algo assim com seu comando mogrify de exemplo:

mogrify -crop 250x250+[(width of image - 250)/2]+0 -gravity NorthWest cat.jpg

Qual é um conceito razoavelmente bom, mas não é uma realidade útil. Mas eu apenas experimentei um pouco e fiz isso funcionar para uma única imagem de teste:

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

Como o -gravity default do ImageMagick é NorthWest , você pode simplificá-lo removendo a opção -gravity da seguinte forma:

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

E depois de testar esse conceito, eu preparei este script Bash e ele funciona como esperado. Basta alterar o valor DIRECTORY para corresponder ao diretório real no qual você planeja agir. E que echo mogrify permite que você veja exatamente o que estaria acontecendo se o comando fosse executado; remova esse echo e deixe o script ir se você estiver satisfeito com os resultados:

#!/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
    
por 19.10.2015 / 03:24
0

JakeGould deu uma solução de trabalho, mas acho que uma solução muito mais fácil não é roteirizá-la, mas usar a conversão de duas etapas. Primeiro reduza a altura para 250 pixels com gravidade Norte , depois reduza a largura para 250 pixels com gravidade Centro :

mogrify -gravity North -crop x250+0+0  cat.jpg
mogrify -gravity Center -crop 250x250+0+0  cat.jpg

Como alternativa, você pode usar a conversão com uma imagem intermediária não-jpg para evitar perda de qualidade devido à conversão extra para jpg:

convert -gravity North -crop x250+0+0 cat.jpg png:- | convert -gravity Center -crop 250x250+0+0 png:- cat.jpg
    
por 25.01.2018 / 10:02