Создание растровых изображений с пурпурным фоном в WPF прозрачным
Я нахожусь в процессе преобразования некоторого устаревшего программного обеспечения, которому 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+?
Есть похожий вопрос: сделать часть изображения прозрачной. Но нет однозначного ответа (или я действительно не могу поверить, что это невозможно).
1 ответ
Я закончил тем, что создал новое изображение (32bit 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);
Результат: