1
votes

I'm trying to put overlay (watermark) on base image. Assuming it looks like this:

enter image description here

opaque rectangle with "fully transparent" text on it. I.e. all pixels of text is transparent, as well as background under it.

1 way:

I do opacity 60% in Photoshop:

enter image description here

And just compose it in code:

MagickWand* overlay = NewMagickWand();
MagickReadImage(overlay, overlaypath);
MagickCompositeImage(wand, overlay, OverCompositeOp, 100, 100);
//all open/destroy code is omitted

And result is rectangle is semi-transparent while text is fully transparent:

enter image description here

So far so good, but I also wanted to regulate overlay opacity via application config, so I tried second way:

2 way:

100% in Photoshop (as on very first image in this post) and trying to set transparency via MagickWand:

MagickReadImage(overlay, overlaypath);
MagickSetImageOpacity(overlay, 0.6);
MagickCompositeImage(wand, overlay, OverCompositeOp, 100, 100);

Result is totally blank rectangle, semi-transparent though

enter image description here

It looks like MagickSetImageOpacity set up every pixel alpha channel to the same 0.6 value regardless of its current value. What I need is currentAlpha -= givenAlpha for every pixel of overlay wand. Is this possible without iterate every wand pixel by hand?

1

1 Answers

2
votes

The correct way to achieve the currentAlpha -= givenAlpha would be to invoke a PixelIterator, and iterator through each pixel, and apply the givenAlpha with PixelSetAlpha. But for you needs, you may be able to apply the same effects with MagickColorizeImage.

PixelWand *pColorize = NewPixelWand();
PixelWand *pGivenAlpha = NewPixelWand();
double userOpacity = 0.6;

// May need to be adjusted to "white" or "black" depending on your mask
PixelSetColor(pColorize, "transparent");
PixelSetAlpha(pGivenAlpha, userOpacity);

MagickWand *overlay = NewMagickWand();
MagickReadImage(overlay, overlaypath);
MagickColorizeImage(overlay, pColorize, pGivenAlpha); // Apply opacity filter
MagickCompositeImage(wand, overlay, OverCompositeOp, 100, 100);