Page 1 of 1

Applying alpha mask to image (C++)

Posted: 2015-04-28T02:59:46-07:00
by TheZombieKiller
(Cross-post from StackOverflow, in the hopes that I'll get an answer either over there, or over here)

I have an image, that has a sequence of two frames. The second frame is supposed to be an alpha mask for the first frame.

Here is an example:

http://i.imgur.com/c2M10u7.png

I've written the following code using Magick++ to split the image into two halves, and apply the alpha mask:

Code: Select all

#include "stdafx.h"
#include <iostream>
#include <Magick++.h>

int main(int argc, char **argv)
{
    Magick::InitializeMagick(*argv);

    Magick::Image base, mask;
    std::string image;

    if (argc > 1)
    {
        image = argv[1];
    }
    else
        return EXIT_FAILURE;

    // Read image
    base.read(image);
    mask = base;

    // Crop out mask and sprite
    base.crop(Magick::Geometry(base.columns() / 2, base.rows(), 0, 0));
    mask.crop(Magick::Geometry(mask.columns() / 2, mask.rows(), mask.columns() / 2, 0));

    // Apply mask
    base.composite(mask, 0, 0, Magick::BlendCompositeOp);

    // Write
    base.write("output.png");

    return EXIT_SUCCESS;
}
However, I can't figure out how to actually apply this as an alpha mask, rather than just blending it. I cannot find a solution for it anywhere either, at least not for C++.

Any help would be greatly appreciated.

Re: Applying alpha mask to image (C++)

Posted: 2015-04-28T03:51:30-07:00
by dlemstra
You should use CopyOpacity (http://www.imagemagick.org/Usage/compose/#copyopacity) instead of Blend. And your mask looks inverted so you might have to negate it.

Re: Applying alpha mask to image (C++)

Posted: 2015-04-28T03:56:01-07:00
by TheZombieKiller
Using CopyOpacity seems to cause no change in the final image. Note that the mask image is not transparent, it is black and white.

Current code:

Code: Select all

#include <iostream>
#include <Magick++.h>

void convertImage(std::string image)
{
	// Read image
	Magick::Image base, mask;
	base.read(image);
	base.type(Magick::TrueColorMatteType);
	mask = base;

	// Crop out mask and sprite
	base.crop(Magick::Geometry(base.columns() / 2, base.rows(), 0, 0));
	mask.crop(Magick::Geometry(mask.columns() / 2, mask.rows(), mask.columns() / 2, 0));

	// Apply mask
	mask.negate();
	base.composite(mask, 0, 0, Magick::CopyOpacityCompositeOp);

	// Write
	base.write("output.png");
}

int main(int argc, char **argv)
{
	Magick::InitializeMagick(*argv);
	
	for (int i = 1; i < argc; i++)
	{
		convertImage(argv[i]);
	}

	return EXIT_SUCCESS;
}

Re: Applying alpha mask to image (C++)

Posted: 2015-04-28T03:59:52-07:00
by dlemstra
You should also disable the alpha channel for this to work. I should have posted that here but I was hoping you would read the information on the usage page:
Images using this operator should NOT contain any alpha channel.

You can ensure that the images do not have any alpha channel by Turning Off the Alpha Channel. on both input images before compositing using the 'Copy_Opacity' compose setting.
p.s. I have moved your topic to the correct spot.

Re: Applying alpha mask to image (C++)

Posted: 2015-04-28T04:01:54-07:00
by TheZombieKiller
Sorry about that, I skimmed the page and didn't notice that part.
What function is used in Magick++ to disable the alpha channel? All of this documentation seems to be for the command line utility, and not the API.

EDIT: Nevermind, by typing out random names as guesses, I found the function names thanks to Visual Studio's autocomplete feature. Here's the final code if anyone ever has the same issue and finds this thread via Google:

Code: Select all

#include <iostream>
#include <Magick++.h>

void convertImage(std::string image)
{
	// Read image
	Magick::Image base, mask;
	base.read(image);
	base.type(Magick::TrueColorMatteType);
	mask = base;

	// Crop out mask and sprite
	base.crop(Magick::Geometry(base.columns() / 2, base.rows(), 0, 0));
	mask.crop(Magick::Geometry(mask.columns() / 2, mask.rows(), mask.columns() / 2, 0));
	
	// Apply mask
	mask.negate();
	mask.alphaChannel(MagickCore::AlphaChannelType::DeactivateAlphaChannel);
	base.alphaChannel(MagickCore::AlphaChannelType::DeactivateAlphaChannel);
	base.composite(mask, 0, 0, Magick::CopyOpacityCompositeOp);

	// Write
	base.write("output.png");
}

int main(int argc, char **argv)
{
	Magick::InitializeMagick(*argv);
	
	for (int i = 1; i < argc; i++)
	{
		convertImage(argv[i]);
	}

	return EXIT_SUCCESS;
}

Re: Applying alpha mask to image (C++)

Posted: 2015-04-28T04:09:36-07:00
by dlemstra
That method is called matte.

Code: Select all

// Crop out mask and sprite
base.crop(Magick::Geometry(base.columns() / 2, base.rows(), 0, 0));
mask.crop(Magick::Geometry(mask.columns() / 2, mask.rows(), mask.columns() / 2, 0));

// Disable alpha channel
base.matte(false);
mask.matte(false);

// Invert the mask
mask.negate();

// Apply mask
base.composite(mask, 0, 0, Magick::CopyOpacityCompositeOp);
p.s. I have also answered your StackOverflow post.

Re: Applying alpha mask to image (C++)

Posted: 2015-04-28T04:10:57-07:00
by TheZombieKiller
Ah, that's simpler than how I was going to go about it (see edit above). Thanks a bunch!