How to use mask to remove masked part of Image

Hello,
I know there is parameter fillAlphaChannelWithCurrentBrush in Graphics::drawImage() to use image as a mask.
But actually it only uses current Graphics colour with alpha from image. But I need to remove all pixels which are under the mask.

How to achieve such kind of masking? Maybe I could use Path to create such mask?

For any help great thanks in advance.
Best Regards

I’ve tried to use something like that:
graphics.reduceClipRegion(maskImage, AffineTransform());

But it doesn’t work.
When I just draw image like that:
graphics.drawImageAt(maskImage, 0, 0, true);

Then everything is fine. The problem is it not removing masked pixels, but drawing shape of maskImage with current colour.

if i’m not mistaken, if your path is closed you can tell what’s within and outside

Sorry if my explanation is not clean. So I try to show it.
My main Image is like that:

And my masking Image, or Path is like that:

And I need to achieve that:

Is it possible with Juce::Graphics?

Try Graphics::reduceClipRegion with a Path.

You may need to set your Path to use non-zero winding.

Matt

Hmm… Great thanks for your answer. But as I told before I tried with Graphics::reduceClipRegion(Rectangle<int>(0, 0, 20, 20))
So as I understand it should remove from my graph the rectangle 20x20.
But it doesn’t work.
So I thought that maybe x y coordinates are wrong, maybe 0, 0 is relative to some parent Component or anything like that. So to be sure that coordinates are OK, I tried Graphics.fillRect(Rectangle<int>(0, 0, 20, 20))
And it works fine. It draws rectangle 20x20 as I expect.

But reduceClipRegion doesn’t work.

I’ve just tried also with Path and with no success. I tried both:
Path::setUsingNonZeroWinding(true)
and
Path::setUsingNonZeroWinding(false)

And both don’t work. So I have no idea what I do wrong.

Hmm… Great thanks for your answer. But as I told before I tried with Graphics::reduceClipRegion(Rectangle<int>(0, 0, 20, 20))
So as I understand it should remove from my graph the rectangle 20x20.
But it doesn’t work.

Graphics::reduceClipRegion(Rectangle<int>(0, 0, 20, 20)) will reduce your clip region to the specified rectangle. So it will not remove that rectangle from your clip region. After that call, your clip region will only be 0, 0, 20, 20.

If you want to remove that rectangle from your clip region, try Graphics::excludeClipRegion.

If you’re not sure, try calling Graphics::getClipRegion immediately after changing the clip region.

Matt

Great thanks, but all of that just don’t work for me. I don’t want to use Rectangle, It was just example.

I want to receive something like I showed on pictures. You’ve told to use Graphics:: reduceClipRegion() with path, but I can’t find the way how to use it.

My code is like that:

void MyComponent::paint(Graphics& g)
{
    g.fillAll(Colours::red);

    float width = getWidth(); // Which is 100
    float height = getHeight(); // Which is 100
    Path path;
    path.addEllipse((width/2) - 20.0f, (height/2) - 20.0f, 40.0f, 40.0f);

    g.reduceClipRegion(path);
}

So here I expect to have big red square (100x100), which is totally transparent in a circle in the center of square, and the circle radius is 20.

But g.reduceClipRegion(path); does nothing. It doesn’t matter if I use it or I delete it I still have square which is fully filled with red colour.

First you set the clip path, THEN you draw the square. Right now you fill first and then set a clip-path after. That’s the wrong way around.

For me?
You are genius. :kissing_smiling_eyes:
To be honest I couldn’t find it works because I use:
Image myImage
Graphics myGraphics(myImage)
And later in the code I use:
const Image::BitmapData destData (myImage, Image::BitmapData::writeOnly);
And then set all pixels to something.
So it doesn’t matter if I use myGraphics.reduceClipRegion before or after destData.setPixelColour()

But now I know how to solve it. Thanks all of you.

1 Like