reading pixels from a ImageMagik image?

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
zacwitte

reading pixels from a ImageMagik image?

Post by zacwitte »

I'm trying to use the MagickWand C API to read in a .pgm file and get the grayscale intensities of each pixel into an array, but I'm having trouble figureing out how to get that pixel data once I read in the image. I'm using MagickReadImage() which works pretty well and I've verified it understands the image correctly by outputting it again as a .png file. But I've found the documentation lacking. I guess I can use GetImageFromMagickWand() to get an Image stuct, but I can't find the documentation for whats inside the Image and how to access the pixels. I've found this function called AcquireImagePixels(), but that gives me an array of PixelPackets and I can't find documentation for what a PixelPacket consists of and how to access its members. Plus, I have to somehow detect the image dimensions and generate this ExceptionInfo object. How do I then get those pixels into an int array?


Has whoever is responsible for maintaining the documentation considered using something more similar to JavaDoc or Doxygen? Could make people's lives much easier.

Thanks much for your help!
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: reading pixels from a ImageMagik image?

Post by magick »

The source distribution includes a wand/wandtest.c source module that illustrates accessing pixels:

Code: Select all

  (void) fprintf(stdout,"Utilitize pixel iterator to draw diagonal...\n");
  iterator=NewPixelIterator(magick_wand);
  if (iterator == (PixelIterator *) NULL)
    ThrowAPIException(magick_wand);
  pixels=PixelGetNextIteratorRow(iterator,&number_wands);
  for (i=0; pixels != (PixelWand **) NULL; i++)
  { 
    (void) PixelSetColor(pixels[i],"#224466");
    (void) PixelSyncIterator(iterator);
    pixels=PixelGetNextIteratorRow(iterator,&number_wands);
  }
  (void) PixelSyncIterator(iterator);
  iterator=DestroyPixelIterator(iterator);
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: reading pixels from a ImageMagik image?

Post by anthony »

Can this be put into the 'wand' documentation please.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
zacwitte

Re: reading pixels from a ImageMagik image?

Post by zacwitte »

OK, that code helped a good deal. Examples, I think, are very important in the documentation of an API. It would be really nice if someone mentioned the existence of wanttest.c on the MagickWand API main page and hopefully adds some comments to the actual wandtest.c file.

I'm having some more problems though. I'm trying to read in the pixels values of a greyscale pgm file, which has intensities from 0 to 255 into an array. So I assume PixelGetBlack() would be the correct function for that, but all I get are values of 0. I also tried PixelGetAlpha, but predictably, all I got were values of 1 since the image contains no transparency.

Some other strange phenomenon is that I get random values for the last 18 pixels. (I'm working with 19x19 images) Which is probably due to a simple coding error on my part. The values are always the same every time I run it, regardless of what image file I'm loading.

This is the values of the last 18 elements in my imagepixels[] array as output by printf.

Code: Select all

-0.000000 
0.000000 
-0.000000 
0.000000 
-0.000000 
-0.000000 
-1.998543 
-1.998536 
-0.000000 
0.000000 
-0.000000 
-1.998536 
-0.000000 
0.000000 
0.000000 
919596694055811559401113095282899304729954696342536204743465047440244947124341404649235703820709968908496688687896667912706581481511944562763882660979899035755352187469824.000000 
0.000000 
-0.000000 

Here's the full code:

Code: Select all

#include <wand/MagickWand.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
	MagickBooleanType status;
	
	MagickWand *magick_wand;
	
	MagickWandGenesis();
	magick_wand = NewMagickWand();
	
	status = MagickReadImage(magick_wand, "train-face/cmu_0301.pgm");
	
	if (status == MagickFalse) {
		printf("Error reading image\n");
	}
	else {
		printf("w00t\n");
	}
	
	//char imagepixels[19*19][10];
	double imagepixels[19*19];
	int i=0, j=0;
	
	printf("Utilitize pixel iterator to draw diagonal...\n");
	PixelIterator* iterator = NewPixelIterator(magick_wand);
	//if (iterator == (PixelIterator *) NULL) {
		//ThrowAPIException(magick_wand);
	//}
	
	//this will store the number of pixels in each row
	unsigned long number_wands; 
	
	PixelWand **pixels = PixelGetNextIteratorRow(iterator,&number_wands);
	for (i=0; pixels != (PixelWand **) NULL; i++)
	{
		printf("Number of pixels in this row: %lu \n", number_wands);
		PixelSetColor(pixels[i],"#224466");
		
		//read all the pixels for this row into our own array
		for (j=0; j<number_wands; j++){
			//strcpy(imagepixels[i*(number_wands-1) + j], PixelGetColorAsString(pixels[i]));
			imagepixels[i*(number_wands-1) + j] = PixelGetAlpha(pixels[i]);
		}
		
		PixelSyncIterator(iterator);
		pixels=PixelGetNextIteratorRow(iterator,&number_wands);
 	}
	PixelSyncIterator(iterator);
	iterator=DestroyPixelIterator(iterator);
	
	//write back out to png
	status = MagickWriteImages(magick_wand, "w00tness.png", MagickTrue);
	if (status == MagickFalse) {
		printf("Error writing to png\n");
	}
	else {
		printf("still w00tness!!\n");
	}
	
	for (j=0; j<361; j++) {
		printf("%lf \n", imagepixels[j]);
		//if (j+1 % 19 == 0)
		//	printf("\n");
	}
	
	magick_wand = DestroyMagickWand(magick_wand);
	MagickWandTerminus();
	
	return 0;
}
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: reading pixels from a ImageMagik image?

Post by magick »

We added an example using MagickWand to get and set pixels to the ImageMagick web site (allow 24 hours for the update to mirror). Unfortunately it requires ImageMagick 6.3.5-1 Beta (release date in about a week).
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: reading pixels from a ImageMagik image?

Post by el_supremo »

So I assume PixelGetBlack() would be the correct function for that
What you need is PixelGetRed() (or Green() or Blue() since each pixel should have equal R, G and B values).

[EDIT]: I thought you meant your image was already grayscale but perhaps it is colour and you want the grayscale value. If you get the red, green and blue values you could use intensity = sqrt(r*r+g*g+b*b)

Pete
zacwitte

Re: reading pixels from a ImageMagik image?

Post by zacwitte »

pgm files are only greyscale intensity. Pixel values just range between 0 and 255. If I use PixelGetBlue then 0.400000 is returned for each pixel. Red is 0.13333333 and Green is 0.2777777.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: reading pixels from a ImageMagik image?

Post by magick »

Programmer error. Use 255.0*GetPixelRed(pixels[j]). Note the j rather than the i.
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: reading pixels from a ImageMagik image?

Post by el_supremo »

Two programmer errors methinks. This:

Code: Select all

imagepixels[i*(number_wands-1) + j] = PixelGetAlpha(pixels[i]);
should be this:

Code: Select all

imagepixels[i*number_wands + j] = PixelGetAlpha(pixels[j]);

Pete
Post Reply