Page 1 of 1

Can't modify opacity channel from C++ API

Posted: 2013-08-14T16:16:42-07:00
by drunkensapo
Dear all,
My problem is the following, I have an RGBA image with the alpha channel set to 1 for every pixel, and grayscale image. I want to use the grayscale image as the alpha channel for the other one. I was able to do this successfully from command line using -separate and -combine. However I'm failing to do the same from C++ code. First let me show how I declare images

Code: Select all

//color image
	Color color_red(MaxRGB,0,0,1);
	Magick::Image red( Geometry(640, 480), color_red);
//greyscale image
	Color color_white(MaxRGB,MaxRGB,MaxRGB,1);
	Magick::Image white( Geometry(640, 480), color_white);
	 white.type( GrayscaleType );
I tried the following options:

1) Using composite to copy a channel, just testing with the green channel to get the grasp of it.
It seems to do nothing because white is grayscale.

Code: Select all

red.composite(white, Geometry(0,0,0,0), Magick::CopyGreenCompositeOp);
2) Using MagickCore::CombineImages.
In this point, all available documentation is outdated, saying that this receives a MagickWand struct, which is not true anymore. Thus, this is supposed to combine images but receives only one argument, what is combining with what?

MagickCore::Image* combined2=MagickCore::CombineImages(white.constImage(),MagickCore::GreenChannel,e);

After that I realized that the first argument should be an array of images, but wasnt able to construct it (lack of C++ skills I guess). Couldnt make it compile

Code: Select all

	Magick::Image combine[2];
	combine[0]=white;
	combine[1]=white;
	MagickCore::Image* combined=MagickCore::CombineImages(combine,MagickCore::RedChannel,e);
3) Setting the alpha value for each pixel individually
In this case, the values of opacity I set are completely ignored (matte is on)

Code: Select all

	Pixels view(red);
	size_t columns = 196; size_t rows = 162; 
	Color green_alpha(0,MaxRGB,0,0);
	PixelPacket *pixels = view.get(38,36,columns,rows); 
 for ( ssize_t row = 0; row < rows ; ++row ) 
   for ( ssize_t column = 0; column < columns ; ++column ) 
     *pixels++=green_alpha; 
 // Save changes to image.
 view.sync();
My experience is being awful. The documentation is poor, confusing and even contradictory. I’m starting to think that choosing magick for this project was a mistake.
Any help would be appreciated.
Thanks in advance

Re: Can't modify opacity channel from C++ API

Posted: 2013-08-14T17:27:05-07:00
by drunkensapo
I found a way that works. It beats me why, but in this way I can change the alpha channel.

Code: Select all

Magick::Image* im = new Magick::Image(Geometry(m, n), color_red);
		im->type(TrueColorMatteType);

		// magickIm->depth(8);
		im->modifyImage();


		unsigned long p;
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
			{
				// se guarda por columnas       
				p = MaxRGB;
				if (i < m / 2)
					im->pixelColor(i, j, Color(p, 0, 0, MaxRGB));
				else
					im->pixelColor(i, j, Color(p, 0, 0, 0));
			}

		im->syncPixels();
		im->write("a.png");