我正在将一些15岁的传统软件转换为WPF,其图形通常是一些带有洋红色背景的8位位图,如下所示:
使用Gdi32,使用洋红色作为绘制图形的透明度键是常见的方法。使用System.Drawing
,它将是一个班轮,即_myImg.MakeTransparent(Color.Magenta)
。但是WPF怎么样?对于上述情况,还有标准练习这样的事情吗?
我真的希望这可以开箱即用:
<Image Width="128">
<Image.Source>
<BitmapImage UriSource="Media\opacityTest.bmp" />
</Image.Source>
<Image.OpacityMask>
<SolidColorBrush Color="Magenta" />
</Image.OpacityMask>
</Image>
唉,虽然这是允许的,但它没有做任何事情:
我错过了什么或者在WPF中这是不可能的吗?
最终,我可能必须编写代码将这些位图转换为透明的png,将它们缓存到某处并加载它们。如果是这样,除了Gdi +之外,有没有人知道任何可以帮助我实现这一目标的资源?
有一个类似的问题:Make part of an image transparent。但没有确定的答案(或者我真的不相信它是不可能的)。
答案 0 :(得分:0)
我最终根据原始图像和颜色键创建了一个新图像(32位pargb),这里是代码,无论它的价值如何:
BitmapSource MakeTransparent(BitmapSource img, Color maskColor)
{
var format = PixelFormats.Pbgra32;
var stride = ((img.PixelWidth * format.BitsPerPixel + 31) & ~31) >> 3;
var pixels = new byte[img.PixelHeight * stride];
img.CopyPixels(pixels, stride, 0);
for (var i = 0; i < stride * img.PixelHeight; i += 4)
if (Color.FromRgb(pixels[i + 2], pixels[i + 1], pixels[i]) == maskColor)
for (var j = i; j < i + 4; j++)
pixels[j] = 0;
return BitmapSource.Create(
img.PixelWidth, img.PixelHeight,
img.DpiX, img.DpiY,
format,
null,
pixels,
stride);
}
它不使用System.Drawing
因此不需要Gdi +,它只是修改像素数组替换指定的maskColor
,并将预乘的alpha rgb值设置为0。
用法示例:
TestImage = MakeTransparent(new BitmapImage(new Uri(@"opacityTest.bmp", UriKind.Relative)), Colors.Magenta);
结果: