Applying alpha mask to image (C++)

Magick++ is an object-oriented C++ interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick++.
Post Reply
TheZombieKiller
Posts: 4
Joined: 2015-04-28T02:57:51-07:00
Authentication code: 6789

Applying alpha mask to image (C++)

Post 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.
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

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

Post 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.
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
TheZombieKiller
Posts: 4
Joined: 2015-04-28T02:57:51-07:00
Authentication code: 6789

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

Post 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;
}
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

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

Post 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.
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
TheZombieKiller
Posts: 4
Joined: 2015-04-28T02:57:51-07:00
Authentication code: 6789

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

Post 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;
}
Last edited by TheZombieKiller on 2015-04-28T04:10:05-07:00, edited 1 time in total.
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

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

Post 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.
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
TheZombieKiller
Posts: 4
Joined: 2015-04-28T02:57:51-07:00
Authentication code: 6789

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

Post by TheZombieKiller »

Ah, that's simpler than how I was going to go about it (see edit above). Thanks a bunch!
Post Reply