Imagemagick get real width and heigth - image-processing

magick identify -format "{w: %w, h: %h, o: %[orientation]}" img.png
I run this command to determine the dimensions of an image. The problem is, sometimes the orientation is such that w and h are swapped in practice. How can I get the "actual" dimensions, which a human sees when they open a picture? Is there a built-in command to get those, or a rule regarding when a particular orientation means I have to swap w and h?

You want the -auto-orient option:
magick INPUT.JPG -auto-orient -format "{w: %w, h: %h, o: %[orientation]}" info:

Related

Imagemagick: How to get image width, then use that to batch resize all images in folder to width x width / 2?

I have over 400 images I need resizing. They need to be their individual original widths, but the heights need to be exactly half the width of each image.
I've been trying for 3 hours to get something work in Imagemagick, with no luck.
Any ideas?
Thanks a lot!
magick 40inch_downbelow_001.jpg -ping -resize "x%w/2" 40inch_downbelow_0aaaaaaa01.jpg - This is my current command, which is just a test. This spits out an image of exactly the same size, despite telling it to use half the width.
Here are two ways to accomplish this in Windows, one using ImageMagick v6 and another using v7. These will run all the JPG images in a directory.
Using IMv6...
for %I in ( *.jpg ) do (
convert "%I" -set filename:0 "%[t]XXX.%[e]" ^
+distort SRT "0,0 1,%[fx:w/h/2] 0" -shave 1 "%[filename:0]"
)
Using IMv7...
for %I in ( *.jpg ) do (
magick "%I" -set filename:0 "%[t]XXX.%[e]" -resize "x%[fx:w/2]!" "%[filename:0]"
)
Substitute your file name modifier for the "XXX" I used in the examples. To use these commands in a BAT script you'll need to double the percent signs "%%".
I think you want this, for a single image:
magick input.png -resize "x%[fx:int(w/2)]\!" result.png
The fact there is nothing before the x means the width is left unchanged. The new height is calculated as half the width and the exclamation mark permits distortion of the original aspect ratio.
If you want to do all PNGs in the current directory, use:
#!/bin/bash
for f in *.png; do
magick "$f" -resize "x${h}\!" "$f"
done
If you only have old, v6 ImageMagick, go with:
#!/bin/bash
for f in *.png; do
# Get current width and halve it
w=$(identify -format "%w" "$f")
((h=w/2))
mogrify -resize x${h}\! "$f"
done

Convert images and show result using Image Magick

I am manipulating images using Image Magick. Here is the command that I use:
convert source.png -resize 1200 -quality 75 result.jpg
It works as expected. I am no wondering whether there is a way to report a conversion result showing how much compression has been done (in percentage or kilobyte or just by showing the sizes of original and converted images)?
I have tried -monitor switch, but it only shows a progress kind of report during conversion.
(I am using Linux)
The quality setting you use tells ImageMagick how much to compress the image. Alternately, you can compute the ratio of the output file size by the input size. Or the ratio of the output file size with -quality 75 to that when using -quality 100, even though -quality 100 still compresses some.
You can get the size of the image by
convert image -precision 16 -format "%b\n" info:
Setting a large precision will forces the result to be in Bytes, but you will have to remove the B character from the end. So you can do the following to get the percent of output/input file sizes:
outsize=$(convert output -precision 16 -format "%b\n" info: | sed 's/B//g')
insize=$(convert input -precision 16 -format "%b\n" info: | sed 's/B//g')
percent_size=$(convert xc: -format "%[fx:100*$outsize/$insize]\n" info:)

imagemagick: how to get image size after resize?

I'm resizing my image using imagemagick, however, I'm not specifying the exact size:
convert $filename -resize 1080000# -quality 100 $reduced_filename
it's resized within a bound, now the problem is, after resize, the size in the EXIF is no longer correct, and I don't have a clue of calculating the new size (e.g. percentage resize can let me calculate new size based on percentage).
So is there a way to get image size after resizing?
Thanks!
You can use ImageMagick's "convert" command to access the image dimensions with a command like this...
convert $filename -format "%[w]x%[h]" info:
Like this...
First create a start image 1024x768:
convert -size 1024x768 xc:black start.jpg
Now resize, and output new size info in one fell swoop:
convert start.jpg -resize 50% -format "%wx%h" -write info: result.jpg
512x384

How do I crop using relative offsets in ImageMagick?

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

Dynamic image watermarking - injecting model attributes into watermarks

I'm currently using this Paperclip::Processor to watermark images with imagemagick's composite command.
It allows me to inject a pre-made single file as a watermark, which lives in my public file.
However, I'm trying to work out if it's possible to modify this to dynamically generate watermarks that include model attributes. For example, the watermark includes the name of a photographer, or the model of the camera it has been taken with.
Getty have recently changed their watermark to do just this - it's very clever, and I'm fascinated to know how they've done it.
Many thanks in advance. I'm not expecting people to know exactly how to do this, but any ideas or general principles would be appreciated.
Yes it can be done with Imagemagick; I have done it with php and a batch script. I have no idea how you would convert this batch script into ruby-on-rails though.
You can get most values contained in the EXIF data and use them in some similar code to this.
:: Do not display the code while running
#ECHO OFF
:: Select the F number from the EXIF data and set the FNumber variable
FOR /F %%x IN ('identify -ping -format "%%[EXIF:FNumber]" %1') DO SET FNumber=%%x
:: Set the FNumber1 variable to the F number value
:: Image Magick returns the F number in the format of 700/100 or 40/10
FOR /F %%x IN ('convert xc: -ping -format "%%[fx:%FNumber%]" info:') DO SET FNumber1=%%x
:: Set the value of the shutter variable to the shutter speed
:: Select the shutter speed from the EXIF data
:: Image Magick returns the shutter speed in the format of 810/100
FOR /F %%x IN ('identify -ping -format "%%[EXIF:ShutterSpeedValue]" %1') DO SET shutter=%%x
:: Format the speed to 8.1 and set the speed variable
FOR /F %%x IN ('convert xc: -ping -format "%%[fx:%shutter%]" info:') DO SET speed=%%x
:: Calculate the speed in seconds using the power of 2
:: and save it in the shutterspeed variable
FOR /F %%x IN ('convert xc: -ping -format "%%[fx:floor((pow(2,%speed%)))]" info:') ^
DO SET shutterspeed=%%x
:: Add the F number and shutter speed to the image
:: and save as exif_OriginalImageName
convert %INPUTFILE% ^
-pointsize 16 -fill black -gravity northwest ^
-annotate +10+5 "Aperture: F%FNumber1% Shutter speed: 1/%shutterspeed% sec" "%~p1EXIF_%~n1.jpg"
Thanks for your help Beerlington. I actually worked out a way of doing this by adding convert_options to the image during the paperclip thumbnailing process. So, on the image model, where a is the image:
has_attached_file :image,
processors: [:thumbnail],
styles: {
wide: {
geometry: "1120x",
convert_options: ->(a) { "-quality 92 -font Arial -pointsize 72 -gravity center gradient: -alpha on -channel rgba -fill 'rgba(255,255,255,0.3)' -opaque 'rgba(20,20,20,1)' -draw \"text 0, 340 #{a.picusername}\" -pointsize 30 -draw \"text 0, 390 'license copy here'\"
"}
}
This writes a.picusername on the image with various placement and styling details. You can find more of these here.
A final note - If you are adding attributes to the image model using something like simpleform, the above processing instructions are applied at the instant the image itself is added to the db... so any model attributes added after the image attachement (literally, in the form inputs below the image attach) will not be recognised, as they don't yet exist.

Resources