ImageMagick crop with percentage like CSS background-position
November 8, 2021
background-position
November 8, 2021
Another one of those posts that are probably only useful to me, but who knows!
I’ve been wanting to crop images with ImageMagick in a way that mimics
what the CSS background-position
property does.
background-position
behave?Let’s say I have a picture that I’m making shorter, e.g. a 1:1 picture that I want to make 16:9, and I want to make sure to keep it centered both horizontally and vertically. I would use the following:
.element {
background-position: 50% 50%;
}
In this particular case, we can easily mimic that with ImageMagick.
Let’s assume input.jpg
is currently a 1080x1080 square picture, and we
want to scale it down to a 640x360 16:9 landscape:
convert input.jpg -resize 640x -gravity center -crop 640x360+0+0 output.jpg
But -gravity
only allows us to align top (north
), center or bottom
(south
). What if we wanted a percentage in between?
In the case of background-position
, 0% would align the picture at the
top, and 100% at the bottom. Anything in between would allow to navigate
in that range.
Let’s pretend we can’t do -gravity south
to align the crop at the bottom,
and convert our 100% offset to a pixels offset. It would be equal to the
original picture height minus the target crop height, or in the case of
our example, 640 - 360
, which is 280 pixels.
convert input.jpg -resize 640x -crop 640x360+0+280 output.jpg
Similarly, our 75% becomes 75 / 100 * (640 - 360)
, which is 210.
But it gets a bit annoying to calculate that manually every time.
Instead, let me introduce the magick
command!
magick
commandmagick
behaves very similarly to convert
, but supports some extra
features like the ability to embed calculations directly in the cropping
options!
magick input.jpg -resize 640x -crop '640x360+0+%[fx:75/100*(h-360)]' output.jpg
Here, the only variable we have to manually write down is the cropped height, which we already need to know to perform the crop in the first place.
With that, it gets easy to adjust the percentage in a way that’s
consistent with what background-position
would otherwise do, without
having to do the math by hand.
It was already possible to do this by combining identify
and a command
line calculator like bc
, but having the option to do that so easily in
the -crop
option is definitely nicer!