How to batch convert images to a specific megapixel with Imagemagick? - imagemagick

I'm sorting my photos and want to resize them to something reasonable. Now the input files are a wild mix of small and big images, some landscape, some tower.
I want to resize them all (above a threshold) to a specific megapixel size, but all descriptions I found so far only resize to either a fixed size / aspect ratio (e.g. 1024x786) or a fixed percentage (e.g. 50%). None of these seem to apply with a folder that has some small images (e.g. 300x400) and images mixed in the range of 3-12 megapixel.
I'm looking for an aspect ratio independent option that puts them all in the same megapixel ballpark. Any suggestions?

Add \> at the end of your resize to only down-res larger images and not affect smaller ones and maintain aspect ratio too.
convert -resize 1200X800\> image.jpg
Or if you want a specific number of pixels, regardless of whether landscape or portrait, you can do
convert -resize 1000000#\> image.jpg
so you get a million pixels max, which may be 400x2,500 or 2,500x400 for example.
EDITED
I should maybe point out that the backslash in front of the greater than symbol is a shell escape to stop the shell deciding to redirect output like it normally does when it sees a greater than symbol. You could equally enclose the resize specification in single quotes to prevent the shell seeing it. If that doesn't make sense, then the following two commands are identical:
convert -resize 1000000#\> image.jpg
convert -resize '1000000#>' image.jpg

Related

How can I convert image background pattern?

On this similar thread they have been proposed solutions to convert the background color of some image to transparent.
But sometimes the background is a simple pattern, like in this case:
Note the square background pattern.
When processing images, the background does often need to be removed or changed, but firstly you need to detect it (i.e: change its color, or making it transparent). For example, on the above image example, I would like to obtain:
How can I detect/change a specified pattern inside an image?
GUI solutions accepted.
Open source solutions preferred (free at least required).
The simplest solution will be preferred (I would like to avoid installing some hundreds of MB program).
Note: I was thinking about posting this question at Photography
StackExchange site, but I would rather say the mind of a programmer (I
could need to edit dozens of such images) is more close to what I
want. I am not an artist.
This is not a fully developed answer, but it does go some way towards thinking about a method - maybe someone else would like to develop it...
If, as you say, your pattern is specified, you know what it is - good, aren't I? So, you could look for the "Minimum Repeating Unit" of your pattern in your image. In your case it is a 16x16 grid like this:
Now you can search for that pattern in your image. I am using ImageMagick at the command-line, but you can use other tools if you prefer. ImageMagick is installed on most Linux distros and is available for OSX and Windows for free. So, I search for that grid in your globe image and ImageMagick gives me an output image showing white dots at the top-left corner of every location where the two images match:
compare -metric ae -dissimilarity-threshold 1.0 -compose src -subimage-search globe.gif grid.png res.png
That gets me this in file res-1.png
Now the white dots are where the 16x16 "Minimum Repeating Unit" is found in the image, but at the top-left corner so I shift them right and down by 8 pixels to the centre of the matching area, then I create a new output image where each pixel is the maximum pixel of the 16x16 grid in which it existed before:
convert res-1.png -roll +8+8 -statistic maximum 16x16 z.png
I can now invert that mask and then use it to set the opacity of the original image, thereby blanking areas that matched the "Minimum Repeating Unit":
convert globe.gif \( z.png -negate \) -compose copy_opacity -composite q.png
No, it's not perfect, but it is an idea for an approach that could be refined...

ImageMagick: scale JPEG image with a maximum file-size

I have a number of JPEG pictures which I would like to scale down. Another requirement is that the file size should not be larger than say 300kByte.
Is that possible, please help me with an example =)
To restrict the resulting image to a maximum file size, you can use the commandline parameter -define jpeg:extent=max_value, like this:
convert original.jpeg -define jpeg:extent=300kb output.jpg
convert original.jpeg -define jpeg:extent=300kb -scale 50% output.jpg
convert original.jpeg -define jpeg:extent=300kb [...other options...] output.jpg
Note, this will not always work to match the exact size you wanted. You may have asked for 40kb output size, where input is 300kb, and get a result of 48kb.
(Update/Clarification: Output file size may be a bit lower or higher than your file requested size.)
The jpegoptim tool (actual homepage is for multiple programs) works better for me:
jpegoptim -s -S8 *.JPG
-s means to strip all metadata (EXIF, JFIF, XMP, etc.)
-S8 means to target a filesize of about 8 KiB
You can crunch them even better by running it twice, because empirically, most images are smaller as progressive:
jpegoptim -s --all-progressive -S8 *.JPG; jpegoptim -s --all-normal -S8 *.JPG
jpegoptim will normally refuse to write an image that increases the size, so this will give you optimum quality/size.
As for the image dimensions part: You normally define a target size in terms of dimensions first and scale there, only then you define the target file size. This is because, when you display it, you ideally want the image dimensions being an integer multiple or fraction of the final display dimensions, to make scaling easier, or even unnecessary. So, scale to the target dimensions first (with quality 100, and possibly other things like 4:4:4 chroma, and most certainly with dct float), then downsize the file. If you can’t get to the file size range you want, choose smaller target dimensions and restart (from the original image, not the one you scaled down first).

getting a limited number of files from imageMagick

I'm trying to make a compilation of 3 thumbs which cover the top of an image. I'm using the following command line command for that:
convert cap/test.jpg -resize 300x -crop 100x135 -strip cap/t.jpg
this resizes the image and cuts it up in 100x135 tiles. But I get more than the top 3 only. I don't need those. I can simply keep the first 3 and delete the rest, but that feels like inefficient programming. Is there a way to limit the number of files written by imageMagick to 3?
eventually I fixed this by making one image with a fixed width and height which I then cut up in 3 separate images. Seems like double work though, since the images are processed twice. Can't be good for the quality either. So here's the workaround:
convert cap/test.jpg resize 300x -gravity north -crop 300x135+0+0 -crop 100x135 -strip cap/t.jpg
but like I said, this processes the image more that absolutely necessary I think. If anybody knows a better solution I'm very interested!

Resize lots of images (with different proportions) so each image fit in a predefined rectangle

I have about 60 images uploaded to my site. I'd like to resize them all so they fit in a 150px × 100px box. No cropping, just scaling, but it should preserve the original proportions.
I'd prefer a simple solution using, say the ImageMagick convert command. A solution for a single arbitrary image is perfectly fine. (I know how to loop or use find in bash.)
The images are of different types (eps, jpg, ps etc) so a solution that at the same time rasterizes the image would be awesome.
Ok, it seems it was easier than I expected:
convert image.eps -scale "150x100>" file_resized.jpg
did the trick. Reference page.

Facebook-like resizing of images using ImageMagick

I would like to resize (downscale) some images the way that Facebook does it. ImageMagick, but hey, I'm open for suggestions :)
I believe Facebook is doing this:
Say you have a max width x height of 250x200, Facebook is optimizing the use of this. Tries to use as much of the 250x200 as possible. If for instance you scale down an image and get 220x200, then they cut from the top and the bottom of the image until they use as much as possible of the 250x200 frame. Actually I think they take more from the bottom, than the top (around 1:2.5), which I believe is because most pictures have the head at the top and Facebook realizes this.
Is there any name for this kind of resizing algorithm? And is there any way to have ImageMagick do this?
Thanks in advance!
Edit
It actually appears that Facebook might not be doing this "smart" resizing technique after all. They just resize where they have a minwidth/minheight. Then when they show the image in their album, they cut from the top/bottom or left/right to use as much as possible for the frame (that is how I perceive it at least).
-Tobias
You can use ImageMagick to get the dimensions of an image, scale then crop it. As to whether you are accurately describing the algorithm Facebook uses, I don't know.
I think the following link addresses the problem you're trying to tackle:
http://www.imagemagick.org/Usage/resize/#space_fill
The example they give at the very end is...
convert logo: \
-resize 160x -resize 'x160<' -resize 50% \
-gravity center -crop 80x80+0+0 +repage space_fill_2.jpg
That command resizes an image to be 160 pixels wide, resizes it to be 160 pixels tall, takes the larger of the two resized images and shrinks it by half, and crop it to 80x80.
The following may be of interest to you:
http://www.google.com/search?q=image+entroy+cropping
I've read several documents about using image entropy to choose what part of the image to crop.
Another related link -
Django, sorl-thumbnail crop picture head
edits: added related links, specified an example command for doing a similar task with link to source of example.

Resources