Assign a single colour to a range of pixels

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
CHRISTOPHERHENRY

Assign a single colour to a range of pixels

Post by CHRISTOPHERHENRY »

Hello,

First of all I love ImageMagick. I am writting code using Visual C++ 2005 and it is working great.

I would like to know if it is possible to assign one colour to all the pixels in a range. I am asking this because I am colouring blocks of an image and this seems to be the slowest part of my program. Maybe it could be done more efficiently. I am using the function pixelColor(col,row,Color(R,G,B,0)) to colour my image.

Thanks
koopa

Re: Assign a single colour to a range of pixels

Post by koopa »

C++ so using the Magick++ interface?

Look for a post only a few days old titled "pixelColor() is slow". I don't fully understand the pixel caching and thread-safety issues here.

My totally unfounded guess is
-Chris
CHRISTOPHERHENRY

Re: Assign a single colour to a range of pixels

Post by CHRISTOPHERHENRY »

Hi Koopa,

Many thanks for your help. I will look at the post you mentioned and try your suggestions. I will be sure to post any improvements I find.

Thanks,

Chris
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Assign a single colour to a range of pixels

Post by fmw42 »

see -fuzz option from command line IM

http://studio.imagemagick.org/script/co ... s.php#fuzz
CHRISTOPHERHENRY

Re: Assign a single colour to a range of pixels

Post by CHRISTOPHERHENRY »

Whoops! Almost forgot to post my solution.

I ended up creating a char array, and coloring the pixels in the array. Then, when I was ready to write the image to a file, I did the following:

Image oI1(columns,rows,"RGB",(StorageType)1,oImage1);
oI1.write(path1);

where oImage1 is my char array. This definitely decreased the execution time.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Assign a single colour to a range of pixels

Post by fmw42 »

Could you post an example (before and after) of what you are doing? It was not clear what you meant by color all pixels in a range. I had thought you meant a range of gray values, but now I think you mean a range of pixe in rectangular or square blocks of coordinates.
CHRISTOPHERHENRY

Re: Assign a single colour to a range of pixels

Post by CHRISTOPHERHENRY »

I am writing an image processing application. The input is an image and the output is an image of the same size divided into square/rectangular regions where all the pixels in a region are assigned the same colour (each colour has a specific meaning).

Previously, I was using pixelColor(x,y,regionColour) to colour all the pixels in the region. However, this part of my code took a long time to execute. Consequently, I posted my question here asking if there is a function that will assign a single colour to a continuse range of pixels. The solution I used was to create a 1D char array and put all the values into the array. Once I was finished assigning colours, I created an image using the method described in my previous post.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Assign a single colour to a range of pixels

Post by fmw42 »

If the size of every region is the same, then you can build an image with just one pixel per color (using -draw point) and then use -filter box -resize (to the size or percent you want for your output).

example:

convert -size 3x2 xc:black \
-fill red -draw "point 0,0" \
-fill green -draw "point 1,0" \
-fill blue -draw "point 2,0" \
-fill yellow -draw "point 0,1" \
-fill magenta -draw "point 1,1" \
-fill cyan -draw "point 2,1" \
-filter box -resize 90x60 blocks.gif

Image
CHRISTOPHERHENRY

Re: Assign a single colour to a range of pixels

Post by CHRISTOPHERHENRY »

Hi fmw42,

Thanks for your help. However, I am using the Magick++ C++ API.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Assign a single colour to a range of pixels

Post by fmw42 »

But can you not convert my command line into the equivalent commands for C++ API? Unless I have misinterpreted what you are trying to achieve, there should be the equivalent in Magick++.
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: Assign a single colour to a range of pixels

Post by el_supremo »

This C code creates the coloured blocks by drawing rectangles rather than using Fred's command line method of drawing single points and then resizing.
You should be able to figure out what's required with C++ from this.

Pete

Code: Select all

#include <windows.h>
#include <wand/magick_wand.h>
void Draw_Coloured_Rectangle(DrawingWand *d_wand,char *colour,double x1,double y1,double x2,double y2)
{
	PixelWand *p_wand = NULL;

	p_wand = NewPixelWand();
	PixelSetColor(p_wand,colour);
	DrawSetFillColor(d_wand,p_wand);
	DrawRectangle(d_wand,x1,y1,x2,y2);
	if(p_wand)p_wand = DestroyPixelWand(p_wand);
}

void test_wand(void)
{
	MagickWand *m_wand = NULL;
	PixelWand *p_wand = NULL;
	DrawingWand *d_wand = NULL;

	MagickWandGenesis();

	m_wand = NewMagickWand();
	p_wand = NewPixelWand();
	d_wand = NewDrawingWand();

	// Create the initial 3x2 image
	PixelSetColor(p_wand,"black");
	MagickNewImage(m_wand,90,60,p_wand);

	// Draw each rectangle
	Draw_Coloured_Rectangle(d_wand,"red",0,0,29,29);
	Draw_Coloured_Rectangle(d_wand,"green",30,0,59,29);
	Draw_Coloured_Rectangle(d_wand,"blue",60,0,89,29);
	Draw_Coloured_Rectangle(d_wand,"yellow",0,30,29,59);
	Draw_Coloured_Rectangle(d_wand,"magenta",30,30,59,59);
	Draw_Coloured_Rectangle(d_wand,"cyan",60,30,89,59);

	// Draw the previous data on to the magick wand image
	MagickDrawImage(m_wand, d_wand);

	/* Write the image as a GIF */
	MagickWriteImage(m_wand,"blocks.gif");

	/* Clean up */
	if(m_wand)m_wand = DestroyMagickWand(m_wand);
	if(d_wand)d_wand = DestroyDrawingWand(d_wand);
	if(p_wand)p_wand = DestroyPixelWand(p_wand);
	MagickWandTerminus();
}
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Assign a single colour to a range of pixels

Post by fmw42 »

el_supremo has a good point. I did not need to do -resize as I could just as easily drawn colored rectangles as points. It was just easier to know how to place points than to place 4 points for rectangles.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Assign a single colour to a range of pixels

Post by anthony »

I have a script called de-pixelate which will given an image (and optionally some pixel size limits) reduce an image of rectanges down to single pixel elements.

It just reduces the image by deleteing duplicate rows and columns, so does not care about the size of the input grid (though limits can be set to handle duplicate rows/columns)

It should reduce your grid to single pixel array very simply!

One enhancement (for the future) would be a 'fuzzy' matching of the duplicate rows and columns, so that pixelated JPEG images can be reduced. In that case the duplicate row/columns of pixels, should be averaged together, rather than just deleted, so as to get a average color for each rectangle.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
CHRISTOPHERHENRY

Re: Assign a single colour to a range of pixels

Post by CHRISTOPHERHENRY »

fmw42: At first I did not follow your line of reasoning. It makes perfect sense to convert commands to
equivalent code in C++. I need to turn my brain on before posting. :)

el_supremo: Many thanks for the code. I will try what you wrote and report back which is faster, i.e.
using your code, or simply using a char array as I did above.
Post Reply