问题
The story
An overview of what I want to accomplish: I have photos that need to be cropped and resized, once for a thumbnail view (around 295x195), and once for a "header-image" style view (around 1400x560). The original photos vary in size, the biggest are around 2440x1600. This would not be a problem to solve.
However, the image should not be cropped with a "North" or "Center" gravity but should have a defined center position from where the
image should be cropped. For this, an image has x
and y
values that represent the center point in percentage; x=50,y=50
would mean
that the focus point of the image is actually in the middle.
I searched here and on the imagemagick forums but could not find anything suitable, except for "cutting off a certain part of an image and then resize it". I'm not sure if this can be done in one imagemagick command or if I need to calculate everything on my own and basically create an empty canvas, put the image on it, move and resize the image, and then shave off everything else to achieve this.
What I want to achieve
I need one imagemagick command to
- take one image as input
- resize and crop it to a given size (e.g. 295x195) respecting the focus point I have (either in percentage or pixels)
- output the image in the given size with the focus point in the middle
I will be using one command per image and per size needed.
Here's a short visualization I made in sketch with a demo picture in hope to make it more understandable what I am trying to do:
The image on the left is the base image on which I put on a focus point at 282,282. The one on the right is the desired crop that I want in 295x195px dimensions (without the lines on it, they're just for the problem demonstration). As you can see, the crop has its center point where the focus point on the original image is.
What I tried
My first attempt was to play around with the offset values for -crop
to set the focus point of the image:
convert photo.jpg -resize 1440x560^ -crop "1440x560+25%+25%" result.jpg
But I learned quickly that this is not the way it works as it results in images being too small (when the coordinates are e. g. in the bottom left of an image) and in general cuts off parts of the image that would be visible with the focus point, which makes sense after reading about it in the docs.
Then I saw the -region
option and tried to play around with it having an image size of 2400x1600 and getting various cuts out of my image:
convert photo.jpg -region 610x400 -resize 1440x560^ -crop 1440x560+0+0 result.jpg
The only effect of the region option is that I get the same cut of the image regardless of what values I put into, and it always puts distorted white horizontal stripes on the image.
Any hints towards the right direction (with or without code examples) would be helpful so I know where to dig deeper.
The environment
- macOS Catalina for development
- app containing the code will run on debian buster
- local imagemagick version is 7.0.8-66
- server imagemagick version is 6.9.10-23 (I can update this with a manual build, though, it would be okay to have a solution that only works in IM7)
回答1:
The "-distort SRT" operator in ImageMagick can scale an image, resize the canvas, and move a point from one set of coordinates to another all in one move.
This command would read your input image and set an output viewport of 295x195. Then it uses "-distort SRT" to scale the input image to 50%, move that starting center point of +282+282 to the new output center point of +147.5+97.5, and change the viewport size to 295x195.
convert input.png -set option:distort:viewport 295x195 \
-distort SRT "282,282 0.5 0 147.5,97.5" result.png
The distort arguments start with the point you want to be the center of the operation, "+282+282". Then the scale "0.5" reduces the size to 50%. The "0" argument is for how many degrees of rotation, but you're not rotating the image, so "0". And the last argument is the landing spot, "+147.5+97.5", for what was the starting point, so it becomes the new center of your 295x195 output canvas.
Of course you'll have to manually insert and adjust your arguments if you're using various sized inputs.
EDITED TO ADD...
ImageMagick can calculate the amount to scale the image using an FX expression. Here is the same command where the FX expression divides the X offset, or the center of the output viewport, by the X offset used from the input image.
convert input.png -set option:distort:viewport 295x195 \
-distort SRT "282,282 %[fx:147.5/282] 0 147.5,97.5" result.png
That puts the original 282 X coordinate point at 147.5, and scales the image to that ratio.
来源:https://stackoverflow.com/questions/60995032/crop-and-resize-image-around-a-custom-focus-point