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

3
能否使用Graphics::DrawImage绘制图像的透明度掩模(即,使用恒定颜色绘制所有可见像素)?我不是要手动逐像素扫描图像并创建单独的掩模图像,我想知道是否可以直接从原始图像中绘制一个掩模。我的猜测是,如果可能的话,应该通过对ImageAttributes进行某些操作来完成。
掩模的颜色是任意的,应该准确无误,并且如果有透明度的阈值就更好了。
2个回答

1

我需要使用每像素的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)

0

您的意思是要将位图中的每种现有颜色转换为一种统一的颜色,同时完全尊重图像中存在的 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;

我不太明白你所说的“如果能有透明度的阈值就更好了”的意思,所以也许这不是你想要的答案?

不完全是这样。变换需要仅在可见/不可见方面尊重源alpha(而不是通过维护它来实现)。因此,阈值表示可见性限制(即alpha>=20 ? visible : invisible)。所有可见像素应使用统一的颜色绘制,所有不可见像素则不应绘制。统一的颜色应为ARGB(而不仅仅是RGB),并且应准确(我不确定浮点数能够多好地保持1/255)。 - sold
啊,我想我错过了什么!好吧,我肯定会通过逐像素扫描来创建一个新的图像。至少这比使用ImageAttribute解决方案要快得多。 - Dan Byström

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接