GDI+,使用DrawImage绘制源图像的透明蒙版

发布于 2024-08-06 21:47:16 字数 204 浏览 4 评论 0原文

是否可以使用 Graphics::DrawImage 绘制图像的透明蒙版(即用恒定颜色绘制所有可见像素)?我不想手动逐像素扫描图像并创建单独的蒙版图像,我想知道是否可以直接从原始图像中绘制一个。

我的猜测是,如果可能的话,应该通过对 ImageAttributes 进行某些操作来完成。

遮罩的颜色是任意的,并且应该是准确的,如果可以有透明度的阈值,那就更好了。

Is it possible to draw a transperancy mask of an image (that is, paint all visible pixels with a constant color) using Graphics::DrawImage? I am not looking for manually scanning the image pixel-by-pixel and creating a seperate mask image, I wonder if it's possible to draw one directly from the original image.

My guessing is that it should be done with certain manipulations to ImageAttributes, if possible at all.

The color of the mask is arbitrary and should be accurate, and it would be a plus if there can be a threshold value for the transparency.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流云如水 2024-08-13 21:47:16

我必须使用每像素 alpha 蒙版绘制图像,发现最好的方法是只绘制基础 RGB 图像,然后在顶部绘制 alpha 蒙版的不透明部分。您需要将每个 Alpha 级别映射到 Alpha 级别 + 颜色,以使图像尊重 Alpha 蒙版中的每个细节。我得到的代码将 alpha 蒙版作为单独的 8 位图像,但绘制代码如下所示:

g.DrawImage(&picture, r.left, r.top, r.Width(), r.Height()); // base image      

if ( AlphaBuf != NULL ) // do we have and alpha mask?
{
Gdiplus::Bitmap mask(Width, Height, Width(), PixelFormat8bppIndexed, AlphaBuf);
picture.GetPalette( palette, picture.GetPaletteSize() );
    // invert - only shows the transparent  
palette->Entries[0] = DLIMAKEARGB(255, 0, 0, 200); // 0 = fully transparent
palette->Entries[255] = DLIMAKEARGB(0, 0, 0, 0); // 255 = fully opaque 

mask.SetPalette(palette);
g.DrawImage(&mask, r.left, r.top, r.Width(), r.Height()); // draw the mask 
}

我的 alpha 蒙版只是完全透明或完全不透明,但我认为在调色板中设置其他 alpha 值可以让您遵循更加有层次的面具。

palette->Entries[1] = DLIMAKEARGB(254, 0, 0, 200);
palette->Entries[2] = DLIMAKEARGB(253, 0, 0, 200);
etc..

希望这有帮助(或者至少有意义:-p)

I have to draw an image with a per pixel alpha mask and found the best way was to just draw the base RGB image then draw the opaque parts of the alpha mask over the top. You need to map each alpha level to an alpha level + colour to get the image to honour every detail in the alpha mask. The code I've got has the alpha mask as a seperate 8bit image but the draw code looks like this:

g.DrawImage(&picture, r.left, r.top, r.Width(), r.Height()); // base image      

if ( AlphaBuf != NULL ) // do we have and alpha mask?
{
Gdiplus::Bitmap mask(Width, Height, Width(), PixelFormat8bppIndexed, AlphaBuf);
picture.GetPalette( palette, picture.GetPaletteSize() );
    // invert - only shows the transparent  
palette->Entries[0] = DLIMAKEARGB(255, 0, 0, 200); // 0 = fully transparent
palette->Entries[255] = DLIMAKEARGB(0, 0, 0, 0); // 255 = fully opaque 

mask.SetPalette(palette);
g.DrawImage(&mask, r.left, r.top, r.Width(), r.Height()); // draw the mask 
}

My alpha masks are only full transparent or full opaque but I would think that setting the other alpha values in the pallette would let you follow a more graduated mask.

palette->Entries[1] = DLIMAKEARGB(254, 0, 0, 200);
palette->Entries[2] = DLIMAKEARGB(253, 0, 0, 200);
etc..

Hope this helps (or at least makes sense :-p )

时间你老了 2024-08-13 21:47:16

您的意思是希望将位图中的每种现有颜色转换为一种统一的颜色,同时完全尊重图像中存在的 Alpha/透明度信息?

如果是这样,只需使用以下颜色矩阵:

imageAttributes.SetColorMatrix( new ColorMatrix( new float[][] {
    new float[] {0, 0, 0, 0, 0},
    new float[] {0, 0, 0, 0, 0},
    new float[] {0, 0, 0, 0, 0},
    new float[] {0, 0, 0, 1, 0},
    new float[] {r, g, b, 0, 1}} ) );

其中 r、g、b 介于 0 和 1 之间,如下所示:

float r = DesiredColor.R / 255f;
float g = DesiredColor.G / 255f;
float B = DesiredColor.B / 255f;

我不明白您所说的“如果可以有透明度阈值,那将是一个加号”是什么意思,不过...所以也许这不是您正在寻找的答案?

Do you mean that you want to transform every existing color in the bitmap into one uniform color, while fully honoring the alpha/transparency information present in the image?

If so, just use the following colormatrix:

imageAttributes.SetColorMatrix( new ColorMatrix( new float[][] {
    new float[] {0, 0, 0, 0, 0},
    new float[] {0, 0, 0, 0, 0},
    new float[] {0, 0, 0, 0, 0},
    new float[] {0, 0, 0, 1, 0},
    new float[] {r, g, b, 0, 1}} ) );

where r, g, b are between 0 and 1, like so:

float r = DesiredColor.R / 255f;
float g = DesiredColor.G / 255f;
float B = DesiredColor.B / 255f;

I don't understand what you mean by "it would be a plus if there can be a threshold value for the transparency", though... so maybe this isn't the answer you were looking for?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文