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

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)]"

Related

How to resize overlay image by ratio and with relative position it from the right?

Let's start with a background and an overlay image:
magick convert -size 500x500! xc:red background.jpg # make a big red background
magick convert -size 100x100! xc:blue overlay.jpg # make a smaller blue overlay
To composite from right side I can use
$geom=magick convert overlay.jpg -print "+%[fx:w+50]+0" null:
magick convert background.jpg overlay.jpg -gravity northeast -geometry $geom -composite output.jpg
However, in my real project, I need to run this with various background images, whose sizes are also various. I would like the overlay to use relative size to the background instead of absolute size.
To overlaying a watermark/logo with relative dimentions, I can use:
magick background.jpg overlay.jpg -resize %[fx:t?u.w*0.9:u.w]x%[fx:t?u.h*0.9:u.h] -gravity northease -composite output.jpg
To resize overlay image by ratio and with relative position it from the right, I try:
magick background.jpg overlay.jpg -resize %[fx:t?u.w*0.1:u.w]x%[fx:t?u.h*0.1:u.h] -gravity northeast -geometry +[fx:t?u.w*0.1:u.w]+[fx:t?u.h*0.1:u.h] -composite output.jpg
But it says:
magick.exe: invalid argument for option '-geometry' '+[fx:t?u.w*0.1:u.w]+[fx:t?u.h*0.1:u.h]' at CLI arg 7 # error/operation.c/CLISimpleOperatorImage/2522.
The documentation for geometry doesn't seem to talk about this. Do you know why?
I'm using v7 on Windows
I miss the %. Correct code:
magick .\base.jpg .\logo.png -resize %[fx:t?u.w*0.1:u.w]x%[fx:t?u.h*0.1:u.h] -gravity northeast -geometry +%[fx:t?u.w*0.03:u.w]+%[fx:t?u.w*0.03:u.w] -composite output.png
See Format and Print Image Properties
The reasoning behind the %[fx:t?u.w*0.9:u.w]
From The FX Special Effects Image Operator:
u: first image in list
v: second image in list
t: index of current image (s) in list
w: width of this image
So in plain language, it means that if the image in question is the second image, whose index is one, of which the ternary conditional operator also read as true, then resize it to 90% width of the first image, else do no resize. Or else -resize option will apply to each images in an image sequence (i.e. all input images before it, but not after it).

imagemagick trim but keep canvas size and *position*

Friends,
I need to -trim some images but keep the original canvas size. Works like this:
convert in.png -fuzz 10% -trim -background white -set page "%[fx:w]x%[fx:h]" +repage out.png
But how can I position the trimmed image part at it's original position? -gravitiy center is not an option as the to-be-trimmed part usually not at the canvas center.
Any ideas?
You should be able to -trim an image, then use -flatten to lay it back onto its original canvas. Try this command...
convert logo: -background none -trim -flatten trimmed.png
#GeeMack's answer is certainly simpler and more succinct, but if you need more flexibility for dinking around, another way is to get the image height and width and the trimbox in one invocation and use them in the next - maybe with adaptation.
So, starting with this image:
# Get image width and height and the trim-box
read geom trim < <(magick start.png -format "%G %#" info:)
# Make a new white canvas same size as original and trim new image onto it
magick -size $geom xc:white \( start.png -crop $trim \) -flatten result.png
I put an artificial yellow border around it so you can see the extent of it on SO's white background.

Imagemagick how to apply gravity and extent to only short images

I have a web page where I list images that should be 600px by 600px (width & height). So I resize all big images to 600x600 using imagemagick, which works fine.
However, some images, when I resize them (in order to keep their aspect ratio), get resized to a size smaller than 600px in height (for example 600x450). So I tried to fill the needed height by using imagemagick options (gravity, background, and extent) like so :
image.combine_options do |img|
img.crop('1200x1200+0+0')
img.resize '600x600'
img.background 'white'
img.extent '600x600'
img.gravity 'center'
end
That gave me what I want for these kind of images (short images). However, this effect of centering is applied to the other images (bigger ones) as well ! Is there any way to prevent that ?
Update:
Just to show you what I mean, I made up this example... if I don't add extent and gravity the image will start from the top left corner
but if I add extent and gravity (center) the image will start from the center, something like this :
I want only images that result on resized images smaller than 600x600 to be centered, but in the example as you see even an image that get resized to exact 600x600 get centered !! that's not what I want
the solution :
I end up using shell command using system function in ruby
system "convert #{image.path} -crop 1024x1024+0+0 -resize 600x600 -background white -gravity center -extent 600x600 output.png"
and that worked fine! I don't know why minimagick wasn't working correctly, but I just get rid of that gem from my gemfile which is fine too.
Here is your command in command line Imagemagick with proper resetting of the virtual canvas after the crop.
convert image -crop 1200x1200+0+0 +repage -resize 600x600 -background white -gravity center -extent 600x600 result
Here are two results with slightly different resize arguments. It looks like your commands are using the equivalent of the ^ flag set on the resize argument.
Input:
Proper result without the ^ flag: (Note padded with white)
convert wiki.png -crop 1200x1200+0+0 +repage -resize 600x600 -background white -gravity center -extent 600x600 result1.png
Result with the ^ flag: (Note cropped)
convert wiki.png -crop 1200x1200+0+0 +repage -resize 600x600^ -background white -gravity center -extent 600x600 result2.png
The above is Unix syntax. For Windows double the ^ to ^^, since ^ is an escape character in Windows.
Perhaps your issue is with minimagick and not Imagemagick. You can check by testing my command line.

ImageMagick: convert image to PDF with A4 page size and image fit to page

I want to convert different image formats (bmp,jpg,gif,png,tiff-incluging multipaged) into a PDF format with A4 page size and with images fit to page (resized if necessary). Image should be positioned at the center of the page and I'd like to define an offset.
I tried the code below but there is no offset at the top and the image quality is really poor.
convert png.png -gravity North -resize 500x500 -quality 100 -page a4x5x5 myout.pdf
Is there any way to do that?
Thanks in advance for any help,
Mariusz
If you want to keep the original resolution (lossless) you can try the following command:
convert png.png -background white -page a4 myoutput.pdf
Based on a comment posted before: https://stackoverflow.com/a/24573341/6747994
#m4tx This command only makes sense if the picture has a resolution above 500x800px, it does not zoom in, to avoid pixelated thumbnails.
You can convert to pdf using ImageMagick
convert png.png myout.pdf
but use pdfjam instead of ImageMagick to adjust the page size
pdfjam --paper a4paper --outfile myoutA4.pdf myout.pdf
pdfjam offers other options, which may fit your needs.
Found this somewhere on stackoverflow:
convert *.jpg -resize 1240x1753 \
-extent 1240x1753 -gravity center \
-units PixelsPerInch -density 150x150 multipage.pdf
Thanks to the ImageMagick support forum I was able to find a solution:
convert image.tif -resize 575x823^> -gravity center -background white -extent 595x842 image.pdf
If you get an error try:
convert image.tif -resize 595x842^\> -gravity center -background white -extent 595x842 image.pdf
You need to specify the density:
convert -density 80 -page a4 input_A.jpg input_B.jpg output.pdf
Otherwise, there can be an issue when printing with "actual size" instead of "fit". I have used a public printer where I could not choose "fit" and had to choose "actual size", in which case the printed page was only a part of the page which I wanted to print.

Use ImageMagick to place an image inside a larger canvas

Getting started with ImageMagic and trying to find a way to do this... If an image is less than 50 pixels tall or 50 pixels wide, I'd like to place it (un-scaled) in the horizontal/vertical center of a new 50x50 pixel canvas on top of a white background - and save that as the new image. Anyone know if this is possible with ImageMagick? Thanks!
I used -extent to do this:
convert input.jpg -gravity center -background white -extent 50x50 output.jpg
I wanted to do the same, except shrink the image to 70% inside. I used this:
convert input.png -resize 70%x70% -gravity center -background transparent -extent 72x72 output.png
Not exactly what was requested but hopefully it will help someone ;).
I have once used this code to place an image in the center of a new canvas with white background. hope this will help you
convert -background white -gravity center your_image.jpg -extent 50x50 new_image.jpg
See cutting and bordering for a huge number of examples. Here's one simple way you might do it:
convert input.png -bordercolor Black -border 5x5 output.png
Of course, you'll need to calculate the size of the border to add (if any) based on the dimensions of the input image. Are you using an ImageMagick API, or just the command line tools?
I tried this:
convert test.jpg -resize 100x100 -background black -gravity center -extent 100x100 output.png
You can use single composition to do this. So it would look something like this:
convert -size 50x50 xc:white null: ( my_image.png -coalesce ) -gravity Center -layers Composite -layers Optimize output.png
To modify the source image you need to use mogrify:
mogrify -gravity center -background white -extent 50x50 source.jpg
If an image is less than 50 pixels tall or 50 pixels wide
In my case, the images were much larger than the destination canvas, and weren't square. So I resize them proportionally to fit inside. Example:
convert in.png -resize 46x46 -background none -gravity center -extent 50x50 out.png
The 46x46 limit ensures a 2 pixel margin minimum. Note that the above does not distort the image, e.g. a rectangle does not become a square.
I used background none for a transparent background, but you can choose a solid color instead.

Resources