DrawingContext.PushOpacityMask() с BitmapImage не работает

Я хочу взять данное изображение BitmapImage и использовать его черно-белое представление в градациях серого в качестве маски непрозрачности для DrawingContext.

Я получил достаточно далеко, чтобы выполнить преобразование цветов, поэтому я получил следующее состояние демонстрационного приложения:

Метод на ViewModel:

public void Demo()
    {
        var width = 400;
        var height = 400;

        var target = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
        var target2 = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);

        var drawingVisual = new DrawingVisual();
        var drawingVisual2 = new DrawingVisual();

        using (var drawingContext = drawingVisual.RenderOpen())
        {
            var bitmapImage = new BitmapImage(new Uri(@"pack://application:,,,/WarningFilled.png"));

            using (var drawingContext2 = drawingVisual2.RenderOpen())
            {
                drawingContext2.DrawImage(bitmapImage, new Rect(0, 0, width, height));
            }

            target2.Render(drawingVisual2);

            var mask = target2.ToGrayscale();
            this.Mask = mask;

            drawingContext.PushOpacityMask(new ImageBrush(mask));
            drawingContext.DrawRectangle(Brushes.Red, null, new Rect(0, 0, width, height));
            // drawingContext.Pop();
        }

        target.Render(drawingVisual);

        this.Rendered = target;
    }

Посмотреть:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpfApplication1="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <wpfApplication1:MainViewModel></wpfApplication1:MainViewModel>
</Window.DataContext>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Border Grid.Column="0" BorderThickness="2" BorderBrush="Blue" HorizontalAlignment="Center">
        <Image Source="{Binding Rendered}" Width="400" Height="400"></Image>
    </Border>
    <Border Grid.Column="1" BorderThickness="2" BorderBrush="Green" HorizontalAlignment="Center">
        <Image Source="{Binding Mask}" Width="400" Height="400"></Image>
    </Border>
</Grid>

Запуск демо-приложения производит это:

Я ожидал, что красный прямоугольник слева будет отражать маску непрозрачности, помещенную в DrawingContext, перед рисованием фактического прямоугольника.

Изображение, которое вы видите справа, является BitmapImage после преобразования цвета, непосредственно перед тем, как оно будет выдвинуто в качестве маски непрозрачности. Как я упоминал ранее, я также пробовал это с черно-белым преобразованием, но даже с двумя цветами это не дает никакого эффекта.

Я пробовал много подобных установок и сценариев, но у меня не работает маска непрозрачности.

1 ответ

Решение

Из статьи Обзор масок непрозрачности на MSDN (выделено мое):

Чтобы создать маску непрозрачности, необходимо применить кисть к свойству Opacity Mask элемента или Visual. Кисть сопоставляется с элементом или визуалом, и значение непрозрачности каждого пикселя кисти используется для определения результирующей непрозрачности каждого соответствующего пикселя элемента или визуала.

Цветовые значения пикселя игнорируются.

Другие вопросы по тегам