문제

Can ImageMagick's convert append white or black bars to maintain aspect ratio after specifying just the aspect ratio?

More concretely

Suppose I have a 2000x1000 widescope image and I would like to compute a new image that has an aspect ratio of 4:3 to fit, say a TV. I can do

convert input.png -background black -extent 2000x1500 -gravity center output.jpg

But here I have manually chosen 2000x1500 to produce an extra 250x2 pixels of blakc. Can I ask convert to:

  1. change the aspect ratio to 4:3
  2. not lose any pixels; not interpolate any pixels
  3. center the image

?

If it's also possible to chose the background color as the dominant color in the image (as in iTunes 11), do mention how.

도움이 되었습니까?

해결책

Convert does not have the built-in capability to pad an image out to a given aspect ratio, so you will need to script this. Here is how this might be done in bash:

#!/bin/bash -e

im="$1"
targetaspect="$2"

read W H <<< $(identify -ping -format "%w %h" "$im")
curaspect=$(bc <<< "scale=10; $W / $H")

echo "current-aspect: $curaspect; target-aspect: $targetaspect"

comparison=$(bc <<< "$curaspect > $targetaspect")
if [[ "$comparison" = "1" ]]; then
    targeth=$(bc <<< "scale=10; $W / $targetaspect")
    targetextent="${W}x${targeth%.*}"
else
    targetw=$(bc <<< "scale=10; $H * $targetaspect")
    targetextent="${targetw%.*}x$H"
fi

echo convert "$im" -background black \
    -gravity center -extent "$targetextent" \
    output.jpg

Call this script with the input image and the target aspect ratio given as a floating point number (for example, 4/3 = 1.333):

$ do-aspect input.png 1.333

Notes:

  • bc is used for floating point math, because bash itself has only integer arithmetic.
  • Note that -gravity center is on the final command line before -extent. This is because gravity is a setting while extent is an operator. Settings should always precede the operators that they affect, or else convert will do unexpected things when your commands start to get more complicated.
  • When you're happy with the results of the program, you can either copy and execute its output, or just remove the echo from before the final convert.

To your question about finding the dominant color of an image, there are different ways of doing that, but one common method is to resize the image to 1x1 and output the color of the resultant pixel - it will be the average color of the whole image:

convert input.png -resize 1x1 -format '%[pixel:p[0,0]]' info:

You can do other processing on the image before resizing to get a different heuristic.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top