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!
Related
I want to overlay multiple PNG images of different sizes on a transparent canvas using ImageMagick. First I create a transparent canvas of some fixed size, say like
convert -size 1500x1000 canvas:transparent PNG32:canvas.png
Then I loop over my images in order to add each image to the canvas
convert canvas.png nthimage.png -gravity Center -geometry xResxYres+xcoord+ycoord -composite canvas.png
This works fine, but I may overlay as many as 10 pictures and I do this for thousands of n-tuples of images, so a faster solution would be appreciated. So my question: Can I also do this in one step instead of creating the canvas first and then adding a single image at a time?
Edit: I use ImageMagick 7.0.11-13 on macOS 10.15.7. I run ImageMagick from within a python script, so a file containing a list of input files can be generated if needed. For concreteness, say my input files are file_1.png up to file_n.png with sizes A1xB1 up to AnxBn and should be placed at coordinates +X1+Y1 up to +Xn+Yn with respect to the center of the canvas and the output file is output.png and should have size 1500x1000.
I really wouldn't recommend shelling out subprocesses from Python to call ImageMagick thousands of times. You'll just end up including too much process creation overhead per image, which is pointless if you are already running Python which can do the image processing "in house".
I would suggest you use PIL, or OpenCV directly from Python, and as your Mac is certainly multi-core, I would suggest you use multi-processing too since the task of doing thousands of images is trivially parallelisable.
As you haven't really given any indication of what your tuples actually look like, nor how to determine the output filename, I can only point you to methods 7 & 8 in this answer.
Your processing function for each image will want to create a new transparent image then open and paste other images with:
from PIL import Image
canvas = Image.new('RGBA', SOMETHING)
for overlay in overlays:
im = Image.open(overlay)
canvas.paste(im, (SOMEWHERE))
canvas.save(something)
Documentation here.
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...
I feel silly for having to ask such a simple question, but I have spent the past hour having absolutely no luck whatsoever finding a solution to this. Everyone seems like they need to do the exact opposite of what I need to do.
My question is simply how do I tell mogrify and/or convert to not keep the aspect ratio when resizing an image? I need the image to be an exact power of 2 for both width and height and the images do not come in a 1:1 ratio which means one side has to stretch.
The closest thing I have to an answer is the -extent flag, but that just extends the canvas. I need the original image to fill the entire thing.
After another half hour of searching I have stumbled upon the overly simple answer. The following will resize an image with the exact dimensions given:
mogrify input.png -resize 256x256! output.png
If you want to read more about it, I got the answer from this link:
https://superuser.com/questions/212752/how-to-stretch-an-image-in-one-dimension
use "!" in convert -resize, for ex:
convert "from-img" -resize 800x480! "to-img"
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.
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.