Page 1 of 1

how to include only certain areas of an image

Posted: 2018-06-09T09:08:37-07:00
by freakin09
Hi,

I am provided with the widths, heights , and coordinates of some rectangles and I need to convert an existing image so that the image after conversion only includes the areas specified by the rectangles. That is, I want to censor all parts of the image that do not fall within the given rectangles.'

I am currently using a command like this to achieve the above :

convert -size dimensionOfImage canvas:SomeColour \(myImage -crop dimensionAndCoordinateOfBox1 \) - geometry coordinateOfBox1 - composite \(myImage -crop dimensionAndCoordinateOfBox2 \) - geometry coordinateOfBox2 - composite myImage

using some example made up numbers, this would be :

convert -size 1000x1000 canvas:black \(myImage -crop 100x100+0+0 \) - geometry +0+0 - composite \(myImage -crop 150x150+200+200 \) - geometry +200+200 - composite myImage

The problem is that this method is slow for my means and also the time required to execute it increases with the number of boxes.

I was thinking of another way which would basically involve drawing the rectangles over the image, saving it to say temp and then comparing temp to the original image to get what is required (although I am unsure of the exact command to do this)

Would be grateful if someone could comment on my approaches and perhaps provide a better(faster) way.

Version: ImageMagick 6.8.9-9 Q16 x86_64 2017-07-31
I am on Ubuntu 16.0.4

Re: how to include only certain areas of an image

Posted: 2018-06-09T09:46:26-07:00
by snibgo
There are many ways to do this that may be faster. For example::

1. Make a same-sized image that is black.
2. On that image, draw white rectangles where you want the original to be visible. This is now a mask, white where you want the original.
3. Make every pixel the darkest of the corresponding pixels from the original and the mask.

Windows syntax:

Code: Select all

convert ^
  toes.png ^
  ( +clone -fill Black -colorize 100 ^
    -fill White ^
    -draw "rectangle 10,10 50,30 rectangle 80,100 180,200" ^
  ) ^
  -compose Darken -composite ^
  justrect_out.jpg
(I've written to JPEG purely for web convenience.)
Image

Re: how to include only certain areas of an image

Posted: 2018-06-09T10:04:07-07:00
by freakin09
Thanks a lot !
Is there a way I could do the above using some other colour apart from black ( I currently using "rgba(0, 255, 255, 255)" and it would be great if I could stick to that) ?

Re: how to include only certain areas of an image

Posted: 2018-06-09T10:10:34-07:00
by GeeMack
freakin09 wrote: 2018-06-09T10:04:07-07:00Is there a way I could do the above using some other colour apart from black ( I currently using "rgba(0, 255, 255, 255)" and it would be great if I could stick to that) ?
You will speed the command by reading in the input image only once, then process clones to extract your individual boxes. As with most IM tasks, there are many ways to approach this. A command like this should do pretty much what you're looking for while eliminating the multiple reads...

Code: Select all

convert input.png -alpha set -background none \
   \( -clone 0 -crop 200x100+50+90 -coalesce \) \
   \( -clone 0 -crop 80x120+200+300 -coalesce \) \
   \( -clone 0 -fill black -colorize 100 \) -delete 0 -insert 0 -flatten result.png
That crops the rectangles and places them on transparent backgrounds while holding their original offsets. Then it flattens them all onto a black background. Change the "-fill" color in the command to place the images on whatever background color you choose. Obviously add more lines of clone, crop, and coalesce to extract more areas.

Re: how to include only certain areas of an image

Posted: 2018-06-09T10:28:53-07:00
by freakin09
thanks a lot !
Could you please tell me what the purpose of "-coalesce" is in the above command

Re: how to include only certain areas of an image

Posted: 2018-06-09T10:40:31-07:00
by snibgo
freakin09 wrote:Is there a way I could do the above using some other colour apart from black...?
Black is the only colour that works in my command, because it is the only colour that is darker than all other colours. Of course, you can then change black to anything else, ("-fill rgba(0,255,255,255) -opaque Black") but that would also change colours within the rectangles.

Alternatively, if your input is fully opaque, you can CopyOpacity the mask, then flatten against any colour you want:

Code: Select all

convert ^
  toes.png ^
  ( +clone -fill Black -colorize 100 ^
   -fill White ^
   -draw "rectangle 10,10 50,30 rectangle 80,100 180,200" ^
  ) -alpha off ^
  -compose CopyOpacity -composite ^
  -background rgb(0,255,255) ^
  -compose Over -layers Flatten ^
  justrect_out2.png

Re: how to include only certain areas of an image

Posted: 2018-06-09T10:52:44-07:00
by GeeMack
freakin09 wrote: 2018-06-09T10:28:53-07:00Could you please tell me what the purpose of "-coalesce" is in the above command
The "-coalesce" places the cropped rectangle onto a transparent canvas of the original dimensions at the original offsets. It might be redundant in this use because the cropped rectangles should all locate at their original offsets after the "-flatten".

Re: how to include only certain areas of an image

Posted: 2018-06-09T12:30:19-07:00
by freakin09
I see.

Thanks a lot @snibgo and @GeeMack !