How do I crop using relative offsets in ImageMagick? - image-processing

For example, this does not work:
convert -crop '69%x27%+3%+13%' +repage source.jpg cropped.jpg
It does not result in an error, but the offset is ignored.
Apparently the offset in a geometry can only be in pixels?
How do I achieve the desired effect?

You can do it like this:
convert -crop $(convert source.jpg -format "%[fx:int(w*0.69)]x%[fx:int(h*0.27)]+%[fx:int(0.03*w)]+%[fx:int(0.13*h)]" info:) +repage source.jpg cropped.jpg
Try running the section inside the $() on its own to see how that generates what you need for the outer command...
convert source.jpg -format "%[fx:int(w*0.69)]x%[fx:int(h*0.27)]+%[fx:int(0.03*w)]+%[fx:int(0.13*h)]" info:
If I run that part of the command on an image 100x100 pixels, I get this
69x27+3+13

Related

Can I refer to the image width and height in an argument?

I want to convert multiple images into square format, filling any empty space with black. Assuming the images have a width of 1000 and a height of less than 1000 (or vice versa), I can do it like this (using PowerShell):
magick.exe convert -background black -gravity center `
-resize 1000x1000 -extent 1000x1000 `
-set filename:original '%t' '.\*.jpg' './%[filename:original]-resized.jpg'
However, I want this to work for arbitrarily sized images. I need to do something like this, which is not an actually supported syntax:
#...
-resize 'max(%w,%h)xmax(%w,%h)' -extent 'max(%w,%h)xmax(%w,%h)' `
# ...
Is there an Imagemagick syntax for what I'm trying to do?
In Imagemagick 7, use magick, not magick convert and move the input parameter to the first parameter position, i.e. magick '.\*.jpg'.
Then, to do what you want change
-resize 'max(%w,%h)xmax(%w,%h)' -extent 'max(%w,%h)xmax(%w,%h)'
to
-resize "%[fx:max(w,h)]x%[fx:max(w,h)]" -extent "%[fx:max(w,h)]x%[fx:max(w,h)]"

ImageMagick - Add white border to many photos with a size relative to the width and height (ex: width * 1.34%)

Is it possible to write a script that can create a copy of all the pictures in a file and add a white border to it with the border multiplied by a certain percentage?
I want the width of the new image (old image + border) to be about 134% of the old one and height about 165% of the old one.
I imagine this is fairly simple but not positive how and all my attempts so far have been unsuccessful.
My current code so far is:
'''for i in ls; do name = "mat_$i" echo "processing $name..." ; convert $i -bordercolor white -border 1x2 $name; done''''
The 1x2 is off for sure, but nothing I have tried there worked either.
I would also like to add meta data as some of these pics are professional and maybe distributed online. Thanks in advance.
Here is one way for Imagemagick 6.
Input:
infile="barn.jpg"
bgcolor="red"
inname=`convert "$infile" -format "%t" info:`
declare `convert "$infile" -format "ww=%[fx:w*134/100]\nhh=%[fx:h*165/100]" info:`
convert -size ${ww}x${hh} xc:"$bgcolor" "$infile" -gravity center -composite "${inname}_pad.jpg"
Result:
For Imagemagick 7, you can do that inline as follows:
magick barn.jpg -size "%[fx:w*134/100]x%[fx:h*165/100]" xc:red +swap -gravity center -composite barn_pad.jpg

Multiple resize operations in ImageMagick

I'm trying to combine some operations using ImageMagick's magick CLI, specifically two operations that resize/scale the image, a random one that does -resize and a bunch of other stuff, plus the answer from this question (Average image color excluding transparency with Imagemagick).
The naive "mix everything together" doesn't work:
magick image -resize 10x10 ... -scale 1x1! -alpha off -format "%[pixel:u.p]\n" info:
...as I get an answer of "black", because this is obviously ignoring my image and using a blank image instead.
I've also tried with subimages (using \( ... \)) but that has the same problem
The following command works fine for me on ImageMagick 6.9.10.16 Q16. What is your ImageMagick version and what other commands do you need in the command line. You only show ...! What else is there? Also can you post your image? You cannot just put "image" in your command line. You have to specify the actual image file and possibly the path to it.
Input:
convert logo.png -transparent white -resize 50% -scale 1x1! -alpha off -format "%[pixel:u.p]" info:
srgb(100,82,99)
Same with IM 7.0.8.16 Q16 HDRI:
magick logo.png -transparent white -resize 50% -scale 1x1! -alpha off -format "%[pixel:u.p]" info:
srgb(100,81,99)
The slight difference is likely a difference from precision with IM 6 (non-hdri) and IM 7 (with hydra).

Remove background, reflection and shadows with Image Magick

I have images where I would like to make the background transparent, remove the shadow and remove the product reflection.
So what I want to do is
Remove reflection
Remove shadow
Remove background
Test image
In Imagemagick 6, you can threshold the image and get the bounds of the black area. Then crop the original to those bounds.
convert image.png -threshold 50% +write image_thresh50.png -format "%#" info:
229x367+39+0
convert image.png -crop 229x367+39+0 +repage image_cropped.png
If using Imagemagick 7, change convert to magick.
Is this what you want?
To follow up on Bonzo's comment, in Unix ImageMagick 6, I could do:
cropvals=$(convert image.png -threshold 50% +write hAfUS_thresh50.png -format "%#" info:)
convert image.png -crop $cropvals +repage image_cropped.png
And in Unix, Imagemagick 7, I could do:
magick image.png \( +clone -threshold 50% -set option:cropvals "%#" +delete \) -crop "%[cropvals]" +repage image_cropped2.png
The reason I did not post these was because I did not know what OS/Platform the OP was using. It always helps when asking questions about Imagemagick to post its version and the platform it is run on.
Sorry I do not know how to do this in Windows syntax

ImageMagick convert rotate crop

The rotate option in ImageMagick's convert tool rotates the image but adds background color to fill the gaps.
I'm looking for a way to rotate and then crop the largest rectangle containing content of the image. Is it possible with convert?
Edited by Mark Setchell...
So, if your original rectangle is a checkerboard created like this:
convert -size 512x512 pattern:checkerboard a.png
and you rotate it through 20 degrees like this
convert -background fuchsia -rotate 20 a.png b.png
you want the largest rectangle that fits on the checkerboard and contains no pink?
You can get an approximation of your expected result by using +repage and replacing -rotate with -distort ScaleRotateTranslate:
convert -background fuchsia -distort ScaleRotateTranslate 20 +repage a.png b.png
After creating the image as indicated:
convert -size 512x512 pattern:checkerboard a.png
This seems to do the work:
angle=20
ratio=`convert a.png -format \
"%[fx:aa=$angle*pi/180; min(w,h)/(w*abs(cos(aa))+h*abs(sin(aa)))]" \
info:`
crop="%[fx:floor(w*$ratio)]x%[fx:floor(h*$ratio)]"
crop="$crop+%[fx:ceil((w-w*$ratio)/2)]+%[fx:ceil((h-h*$ratio)/2)]"
convert a.png -set option:distort:viewport "$crop" \
+distort SRT $angle +repage rotate_internal.png
From here.

Resources