ImageMagick reorients iOS photos - ios

I am currently converting images coming from mobiles apps, i.e. iOS, Android and WP.
I use image magick to resize the photos.
Here is my command line:
convert -resize 764x764 -strip -interlace Plane -quality 85% img1.jpg img2.jpg
It works fine for photos coming from Android and WP however, when I receive it from iOS, the photos are automatically rotated to landscape, even if they are portraits.
Any ideas?
Thank you.

Photo orientation can be defined by the images meta-data. Add the -auto-orient option to respect the EXIF data before removing it with -strip options.
convert img1.jpg -auto-orient \
-resize 764x764 \
-interlace Plane \
-strip \
-quality 85% \
img2.jpg
Warning from docs:
If the EXIF profile was previously stripped, the -auto-orient operator will do nothing.

Related

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).

Imagemagick compose image inverted

I want to watermark an image, so I used compose multiply, but for some reason it doesn't work as expected.
The command:
magick image.jpg over.png -compose multiply -resize 2048x2048 -gravity center -quality 65 -strip -composite out.jpg
The over.png get inverted first and then applied??
If use the same command with and older version of Imagemagick (x32 6.7.6-1 2012-03-17 Q16) I get the expected results.
This was tested with x64 ImageMagick 7.0.5 Q16 under Windows 10.
Ah it seems I can't post all the images.
After a lot of research, turns out it's an artifact of one of the images being a JPEG in CMYK colorspace.
Very weird, but there you go.
Adding '-profile sRGB.icc' to the line should take care of it.
FYI your syntax is not proper. You have separated -compose multiply and -composite with -resize. You should do it this way with nothing between them.
magick image.jpg over.png -gravity center -compose multiply -composite -resize 2048x2048 -strip -quality 65 out.jpg
As you said there will be issues if your input JPG is CMYK and your png will always be sRGB. So you do need to convert the CMYK to sRGB before processing.

Assembling an image from parts of others with ImageMagick (image crop syntax)

I have a set of source PNG images and I want to use parts of them to assemble a final PNG image. The parts are rectangular and never overlap on the destination but are of different sizes. Sometimes it is the whole of a source image and sometimes just a subsection. I want to edit the sources many times and re-assemble the final image each time, so I tried to write a script using sh and Imagemagick to do it.
I tried this
convert \
-size 512x512 null:\
-page +96+32 source_a.png\
-page +96+0 source_b.png[32x32+16+16] \
-background transparent\
-layers merge\
destination.png
(just with two source images for illustration)
I want all of source_a.png and a piece of source_b.png. The first is OK, but using the 'inline crop' syntax on source_b.png gives me an error:
convert: geometry does not contain image `source_b.png' # warning/transform.c/CropImage/666.
The image is big enough:
$ identify source_b.png
source_b.png PNG 64x48 64x48+0+0 8-bit sRGB 3.7KB 0.000u 0:00.000
What's the best way to do this? I am using ImageMagick 6.9.7-0 Q16 on MacOS 10.12
An alternative might be to use -geometry and -composte to achieve the same effect:
convert -size 512x512 xc:white \
source_a.png -geometry +96+32 -composite \
source_b.png[32x32+16+16] -geometry +96+0 -composite \
result.png
PNG's will preserve the paging from inline cropping, so the addition page will through the ROI out of bounds. I imaging it'll be simpler to -repage the inline crop then attempting to clear previous paging & setting new page.
convert -size 512x512 null: \
-page +96+32 source_a.png \
\( source_b.png[32x32+16+16] -repage +96+0 \) \
-background transparent\
-layers merge\
destination.png

imagemagick: follow orientation from exif data

About the ImageMagick command bellow:
imagemagick\convert.exe original.jpg -resize 100x400^ -gravity Center -crop 100x400+0+0 -sharpen 0x0.75 -quality 98% thumbnail.jpg
Some thumbnails generated (in a batch proccess) are not following the original's EXIF data. So they are being generated with the wrong angle. (+|- 90°)
Is there a way to command IM to read the exif data before converting it?
You'll need to add the -auto-orient option.
This operator reads and resets the EXIF image profile setting
'Orientation' and then performs the appropriate 90 degree rotation on
the image to orient the image, for correct viewing.
Example
convert original.jpg -auto-orient -resize 100x400^ \
-gravity Center -crop 100x400+0+0 \
-sharpen 0x0.75 -quality 98% \
thumbnail.jpg

Efficiently generating thumbnails with ImageMagick and convert

I'm looking to efficiently generate various sized thumbnails with ImageMagick's convert utility in Python. Some of my image files are quite large (~15MB JPGs).
One way I could do it would be to take the full-sized image, and to generate the various thumbnails from the full-sized image, as follows:
convert sample_image.jpg -resize 1024x768 sample_image-1024x768.jpg
convert sample_image.jpg -resize 800x600 sample_image-800x600.jpg
convert sample_image.jpg -resize 400x300 sample_image-400x300.jpg
convert sample_image.jpg -resize 200x150 sample_image-200x150.jpg
But another way would be to resize the images from each other:
convert sample_image.jpg -resize 1024x768 sample_image-1024x768.jpg
convert sample_image-1024x768.jpg -resize 800x600 sample_image-800x600.jpg
convert sample_image-800x600.jpg -resize 400x300 sample_image-400x300.jpg
convert sample_image-400x300.jpg -resize 200x150 sample_image-200x150.jpg
Is there any downside to doing this, or perhaps a better way? It seems like this would be a lot more efficient.
As a corollary, are there any flags or "tricks" convert uses to speed up the process?
ImageMagick has a few tricks up its sleeves which help you to optimize for speed when you want to process large images and when you want to create different output from the same original:
Make use of ImageMagick's mpr:{name} feature, which makes it temporarily save the input image into a named memory program register, from which you can later (while processing) read the data much faster than you could do from harddisk.
Do all resize operations in one single process writing out the different output sizes you require.
And the even better news is you can combine both these into one single command.
So you do not need to run multiple processes with all their context-switching overhead -- do it all in one go.
The following example also crops two separate areas from the original image and creates re-sized thumbnails from them, just to show how many different operations IM can do in one commandline. It also, of course outputs the sizes you requested. (You'll need, of course, a really large-dimensioned input image for the cropping parameters to work).
convert \
huge-original.jpg \
-quality 80 \
-colorspace rgb \
+profile '*' \
-filter Lanczos \
-write mpr:copy-of-huge-original \
+delete \
mpr:copy-of-huge-original -crop '3000x2000+0+480' -resize '200x125!>' -write thumb1-extract.jpg +delete \
mpr:copy-of-huge-original -crop '2000x1500+280+220' -resize '75x75!>' -write thumb2-extract.jpg +delete \
mpr:copy-of-huge-original -resize '1024x768' -write sample-1024x768.jpg +delete \
mpr:copy-of-huge-original -resize '800x600' -write sample-800x600.jpg +delete \
mpr:copy-of-huge-original -resize '400x300' -write sample-400x300.jpg +delete \
mpr:copy-of-huge-original -resize '200x150' -write sample-200x150.jpg +delete \
mpr:copy-of-huge-original -resize '163x163!>' -write sample-163x163.jpg
Update
I only now saw the question asked by #JonathanOng: How to stream the output to <stdout>?
Assuming, you want the format going to stdout also be JPEG, you can try this:
convert \
huge-original.jpg \
-quality 80 \
-colorspace rgb \
+profile '*' \
-filter Lanczos \
+write mpr:copy-of-huge-original \
mpr:copy-of-huge-original -crop '3000x2000+0+480' -resize '200x125!>' +write thumb1-extract.jpg \
mpr:copy-of-huge-original -crop '2000x1500+280+220' -resize '75x75!>' +write thumb2-extract.jpg \
mpr:copy-of-huge-original -resize '1024x768' +write jpeg:- \
mpr:copy-of-huge-original -resize '800x600' +write jpeg:- \
mpr:copy-of-huge-original -resize '400x300' +write jpeg:- \
mpr:copy-of-huge-original -resize '200x150' +write jpeg:- \
mpr:copy-of-huge-original -resize '163x163!>' +write jpeg:-
This way each variant will go to stdout. How you deal with this stream of consecutive images then, is up to you...
Note, instead of writing -write filename +delete you can use +write filename. It amounts to the same effect.
I tried timing vipsthumbnail against #KurtPfeifle's excellent answer. I ran this with a 10k x 10k pixel RGB JPG image (about 15MB):
convert \
/data/john/pics/wtc.jpg \
-quality 80 \
-colorspace rgb \
+profile '*' \
-filter Lanczos \
-write mpr:copy-of-huge-original \
+delete \
mpr:copy-of-huge-original -resize '1024x768' -write sample-1024x768.jpg +delete \
mpr:copy-of-huge-original -resize '800x600' -write sample-800x600.jpg +delete \
mpr:copy-of-huge-original -resize '400x300' -write sample-400x300.jpg +delete \
mpr:copy-of-huge-original -resize '200x150' -write sample-200x150.jpg +delete \
mpr:copy-of-huge-original -resize '163x163!>' -write sample-163x163.jpg x.jpg
I found I needed the extra x.jpg at the end, I'm not sure why. On this machine (E5-1650 3.2 GHz, IM 6.8.9-9) I see:
$ time ./m.sh
real 0m6.560s
user 0m31.908s
sys 0m0.264s
peak RES 711MB
This is (I think) the equivalent with vipsthumbnail:
img=/data/john/pics/wtc.jpg
icc=/usr/share/color/argyll/ref/sRGB.icm
for size in 1024x768 800x600 400x300 200x150 163x163; do
vipsthumbnail $img --size $size --eprofile $icc -o vips-sample-$size.jpg[Q=80]
done
vipsthumbnail defaults to Lanczos3. Timing it with vips-8.4.4 I see:
$ time ./n.sh
real 0m2.376s
user 0m2.412s
sys 0m0.108s
peak RES 70MB
So a useful speedup, and a large drop in memory use.
Because memory use is low, you can run many vipsthumbnail in parallel without killing your server. If I change the script to be:
img=/data/john/pics/wtc.jpg
icc=/usr/share/color/argyll/ref/sRGB.icm
parallel vipsthumbnail $img \
--size {} --eprofile $icc -o vips-sample-{}.jpg[Q=80] ::: \
1024x768 800x600 400x300 200x150 163x163
I now see:
$ time ./n.sh
real 0m0.593s
user 0m1.960s
sys 0m0.100s
peak RES 280MB
More than 10x faster than ImageMagick.
For my point of view, and after testing, resizing 1024x768 to 800x600 is bad for rescaling algorithm.
The next resize are more easier, because of multiple of integer (2).
So, for quality reason, I personnaly thing, this is better :
convert sample_image.jpg -resize 1024x768 sample_image-1024x768.jpg
convert sample_image.jpg -resize 800x600 sample_image-800x600.jpg
convert sample_image-800x600.jpg -resize 400x300 sample_image-400x300.jpg
convert sample_image-400x300.jpg -resize 200x150 sample_image-200x150.jpg
15MB JPGs are really large. I would first resize it to reasonable size (say 2500x2500) with fastest "-sample" parameter and this smaller image then resize to different thumbnails.
You can make intelligent decision based on image size and choose the right way of resize.
I would recommend to focus on thumbnail quality instead of conversion speed so please look at different filters (-filter), sharping (-unsharp) and recommended downsampling methods
I'm thumbnailing ~50MB JPG files. The one option which made the biggest difference (~5x speedup) was "-define jpeg:size 128x128" before the input filename. The example given here:
http://www.imagemagick.org/Usage/formats/#jpg_read
...made a huge difference:
convert -define jpeg:size=128x128 jpeg_large.jpg -thumbnail 64x64 jpeg_thumbnail.jpg
-define jpeg:size allows ImageMagick to read in only as much data as it needs from disk, which greatly reduces load time for very large images.
As the linked page suggests, use a jpeg:size= of twice your final thumbnail size to avoid aliasing.
The -thumbnail option, described here:
http://www.imagemagick.org/Usage/resize/#thumbnail
...samples and strips the image, further speeding up the process.

Resources