Calculate the average colour of an area in an image - imagemagick

The goal is to lay a caption on top of an image and set the text colour to one that will contrast with the background it is positioned on top of. To that end, I wish to calculate the average colour of the area inside the red rectangles in the following images:

Expanding on Bonzo’s answer. This is an example command
convert Y82IirS.jpg -resize 1x1 txt:
Result
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (220,176, 44) #DCB02C srgb(220,176,44)
Average colour of an image

I would crop to the area you are interested in then resize it to 1 pixel. Then get the value of that pixel.

Here is a command that handles both cropping and color detection, and also produces output in a consistent R,G,B format:
convert image.gif -crop 6x7+8+9 -resize 1x1\! -format "%[fx:int(255*r+.5)],%[fx:int(255*g+.5)],%[fx:int(255*b+.5)]" info:-
where, in 6x7+8+9 :
6: image width (pixels)
7: image height (pixels)
8: x-coordinate of top left corner
9: y-coordinate of top left corner
Returns
176,191,67
Adapted from https://stackoverflow.com/a/25488429/3124680

Related

Splitting a region of an image into tiles

I have a set of images that are 4500px x 3000px in size.
Out of each of these images I need to extract a set of tiles in a 5 columns by 3 rows combination with each tile being 700px wide by 500px high.
What complicates the above is that the starting point for this needs to be at X:650 and Y:450 position from the top left corner of the image.
I have gotten as far as convert image.jpg -gravity NorthWest -chop 650x450 -crop 700x500 tile-%d.jpg
This gets me to a correct start position for creating the tile set but includes the rest of the blank area in the right and bottom edge of the image.
How do I go about solving this?
Within a single ImageMagick command you can crop the initial rectangle that contains all the tiles first, then crop that into the 15 output images. Try something like this...
convert image.jpg -crop 3500x1500+650+450 -crop 5x3# tile-%02d.jpg

Imagemagick inline border without resizing the original image

I tried to add a border to an image of dimension 200x200 px using the below code.
convert -border 2x2 -bordercolor "#cccccc" old.png new.png
The above code ads a 2 px border around the old.png. Therefore, the image expands to 204x204 px.
However, I want to add an inline border. I have no issues with border overlaying edge portions of the old image. Thus, the new image should be able to retain the dimensions 200x200 px. Please advise how exactly to do that.
You need to shave two pixels all around and then add a two pixel border. You should try this with Imagemagick 6. If using Imagemagick 7, replace convert with magick.
convert old.png -shave 2x2 -bordercolor "#cccccc" -border 2 new.png

How to add a white space around an image using online tools like Pixlr Editor or imagemagick ?

I want to put some white space around an image in equal length. I want to maintain the image pixel ratio to 12:7 too. Any help would do a great help. Thank you.
Another method using Imagemagick V7:
magick ShF4m.jpg -background white -gravity center -extent "%[fx:w+20]"x"%[fx:h+20]" result.jpg
Open image, set the background to white, set the gravity to the centre so the -extent extends the canvas in all directions, increase the canvas size by 20px on the width and 20px on the height.
It would be simple in ImageMagick if you wrote over the inside of the border with white. That way you do not change the image dimensions nor aspect ratio. Here I shave 10 pixels all around and then put a 10 pixel white border all around. Here I will add a red border just to make it visible. But you can change red to white later.
convert barn.jpg -shave 10x10 -bordercolor red -border 10x10 barn_border10.jpg
It would be very hard to add white outside the image of equal amount and keep the aspect ratio. I do not think you can have equal white border amounts and keep the aspect ratio.

GraphicsMagick crop: shows what will be cropped

I'm working on a photo application and I need some advice how should I solve the following with Graphics/ImageMagick.
Given a photo with resolution: 2048x1536
Given a specified resolution: 1864x1228
Resize the image and fill the specified resolution with the image (now it's 1864x1398)
Highlight the area of the original image will be cropped (to 1864x1228)
I have a working solution which resizes and crops the image properly:
IMOperation resizeOp = new IMOperation();
resizeOp.addImage();
resizeOp.resize(MAX_WIDTH, MAX_HEIGHT, "^");
resizeOp.gravity("center"); //centered image with crop the top/bottom parts
resizeOp.crop(MAX_WIDTH, MAX_HEIGHT, 0, 0);
resizeOp.addImage();
ConvertCmd cmd = new ConvertCmd(true);
cmd.run(resizeOp, fileName, outputFileName); //cropped, center filled image (1864x1228)
The question is how should I do the following: show the full image instead of the cropped version and highlight the area of the image will be cropped. I'd prefer with red border around the cropped image and show with the cropped parts with alpha layer.
I have an idea which I don't like very much: generate an image from the original with alpha layer and put the cropped image on it with red border. It doesn't seem to be the optimal solution :) My other idea is to do this with javafx imageviews, but it seems suboptimal as well.
Notes:
I'm using im4java with GM. I accept a command line solution too (and I'll figure out and post it in im4java ;)
We can restrict the conversation about horizontal images only, I can figure out the vertical operations
Any comments would be highly appreciated.
The oneliner imagemagick convert (remove the line breaks):
convert ( in.jpg -resize 1864x1228^ -fill white -colorize 50% )
( in.jpg -resize 1864x1228^ -gravity center -crop 1864x1228+0+0 )
-gravity center -composite out.jpg
In bash, you have to escape the () characters with \!
I solved it in im4java with sub operations:
IMOperation op = new IMOperation();
op.openOperation();
op.addImage(); //input image
op.resize(MAX_WIDTH, MAX_HEIGHT, "^");
op.fill("white");
op.colorize(50);
op.closeOperation();
op.openOperation();
op.addImage(); //input image
op.resize(MAX_WIDTH, MAX_HEIGHT, "^");
op.gravity(GRAVITY_OPT_CENTER); //centered image with crop the top/bottom parts
op.crop(MAX_WIDTH, MAX_HEIGHT, 0, 0);
op.closeOperation();
op.gravity(GRAVITY_OPT_CENTER);
op.composite();
op.addImage(); // output image
Notes:
It still doesn't contain red border (I can't add border only to the second image).
I decided to use "fade to white" effect, instead of playing with alpha channel.
Example:
input: http://i.stack.imgur.com/lhMgT.jpg
output: http://i.stack.imgur.com/EYO7c.jpg

Crop the rectangle region from the image using imagemagick

I have an image. I need to crop the rectangle region from the image. This rectangle region is identified by black color border. Inside the rectangle is what I need. Is it possible to crop the black color bordered rectangle region in imagemagick? I know it could be possible using crop command by providing offset(-crop WxH+X+Y) of the rectangle region. But I want to crop the rectangle region without manually measuring the upper left and lower right corners of the rectangle. Is it possible to crop the rectangle region using black color border alone...???
How about something like this?
convert source.jpg -fuzz 10% -bordercolor black -border 1x1 -trim +repage dest.jpg
You may have to play around with the 'fuzz' percentage. The reason you need the fuzz option is that without it trim will only trim pixels that are exactly black - with JPEGs this is unlikely to be the case.
All this is explained on this page: http://www.imagemagick.org/Usage/crop/#trim
This solution will only work if the black border goes right up to the edges of the image. If this is not the case then I don't think you'll be able to do what you need to with IM without examining the image (e.g. pixel by pixel) programmatically.

Resources