Page 1 of 1

Assign a single colour to a range of pixels

Posted: 2008-07-03T11:22:35-07:00
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

Re: Assign a single colour to a range of pixels

Posted: 2008-07-03T12:39:22-07:00
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

Re: Assign a single colour to a range of pixels

Posted: 2008-07-04T06:44:22-07:00
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

Re: Assign a single colour to a range of pixels

Posted: 2008-07-04T06:58:46-07:00
by fmw42
see -fuzz option from command line IM

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

Re: Assign a single colour to a range of pixels

Posted: 2008-07-14T07:44:05-07:00
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.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-14T11:08:11-07:00
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.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-14T11:26:11-07:00
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.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-14T23:59:28-07:00
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

Re: Assign a single colour to a range of pixels

Posted: 2008-07-15T07:43:35-07:00
by CHRISTOPHERHENRY
Hi fmw42,

Thanks for your help. However, I am using the Magick++ C++ API.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-15T16:16:04-07:00
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++.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-15T16:43:32-07:00
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();
}

Re: Assign a single colour to a range of pixels

Posted: 2008-07-15T19:35:42-07:00
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.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-15T21:06:10-07:00
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.

Re: Assign a single colour to a range of pixels

Posted: 2008-07-16T08:22:32-07:00
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.