2014-01-21 2 views
14

С imagemagick я хотел бы обрезать изображение в минимальном порядке, чтобы он соответствовал данному соотношению сторон.ImageMagick: как минимально обрезать изображение до определенного соотношения сторон?

Пример: с изображением, скажем, 3038 x 2014 px, я хочу обрезать его с соотношением сторон 3: 2. Тогда получившееся изображение будет 3021 x 2014 px, обрезанное, например, по центру исходного изображения.

Ищите команду, выглядящую как-то вроде convert in.jpg -gravity center -crop_to_aspect_ratio 3:2 out.jpg.

+4

Для сценария [Fred's ImageMagick Scripts] есть сценарий (http://www.fmwconcepts.com/imagemagick/aspectcrop/index.php). Он содержит много объяснений о том, как он достигает эффекта. Если вы ведете IM на другом языке скрипта, может быть проще сделать математику там. –

+0

Замечательно! Много полезных вещей там BTW :) –

ответ

0

Вам необходимо выработать требуемые размеры, а затем сделать урожай. Вот функция, которая, учитывая изображения width и height плюс требуемое соотношение сторон как aspect_x и aspect_y, выведет строку обрезки, которая может использоваться с Imagemagick.

def aspect(width, height, aspect_x, aspect_y) 

    old_ratio = width.to_f/height 
    new_ratio = aspect_x.to_f/aspect_y 

    return if old_ratio == new_ratio 

    if new_ratio > old_ratio 
    height = (width/new_ratio).to_i # same width, shorter height 
    else 
    width = (height * new_ratio).to_i # shorter width, same height 
    end 

    "#{width}x#{height}#" # the hash mark gives centre-gravity 

end 

Я использую что-то похожее на это в приложении, которое использует Dragonfly Gem.

9

1. Специфическое разрешение

Если ваша цель в конце концов, иметь определенное разрешение (например, 1920х1080), то это легко, используя -geometry, циркумфлекс/шлет/крыша/символ дома (^) и -crop:

convert in.jpg -geometry 1920x1080^ -gravity center -crop 1920x1080+0+0 out.jpg 

Для цикла по нескольким JPG файлов:

for i in *jpg 
    do convert "$i" -geometry 1920x1080^ -gravity center -crop 1920x1080+0+0 out-"$i" 
done 

2. соотношение сторон урожая ONl y

Если вы хотите избежать масштабирования, вам нужно рассчитать новую длину обрезанной стороны за пределами Imagemagick. Это более активное участие:

aw=16 #desired aspect ratio width... 
ah=9 #and height 
in="in.jpg" 
out="out.jpg" 

wid=`convert "$in" -format "%[w]" info:` 
hei=`convert "$in" -format "%[h]" info:` 

tarar=`echo $aw/$ah | bc -l` 
imgar=`convert "$in" -format "%[fx:w/h]" info:` 

if (($(bc <<< "$tarar > $imgar"))) 
then 
    nhei=`echo $wid/$tarar | bc` 
    convert "$in" -gravity center -crop ${wid}x${nhei}+0+0 "$out" 
elif (($(bc <<< "$tarar < $imgar"))) 
then 
    nwid=`echo $hei*$tarar | bc` 
    convert "$in" -gravity center -crop ${nwid}x${hei}+0+0 "$out" 
else 
    cp "$in" "$out" 
fi 

Я использую 16: 9 в примерах, ожидая, что это будет более полезным, чем 3: 2 для большинства читателей. Измените оба входа 1920x1080 в решении 1 или aw/ah переменных в решении 2, чтобы получить желаемое соотношение сторон.

1

С появлением ImageMagick 7 вы можете использовать выражения FX, чтобы выполнить обрезку с максимальным размером изображения, с учетом соотношения сторон в одной команде.

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

aspect="16/9" 

magick input.png -gravity center \ 
    -extent "%[fx:w/h>=$aspect?h*$aspect:w]x" \ 
    -extent "x%[fx:w/h<=$aspect?w/$aspect:h]" \ 
    output.png 

После того, как аспект права, вы можете следить за две -extent операции с -resize принести готовое изображение на свой выходной размер. Приведенный выше пример сохраняет его как можно больше, поскольку ему может быть предоставлено входное изображение.

Смежные вопросы