如何在WPF C#中创建不透明背景的透明文本

问题描述 投票:0回答:1

每个人都知道如何解决这个问题?

我没有任何代码可提供,因为我不知道从哪里开始,这就是我张贴此代码的原因。

我的计划是在具有隐藏背景图像的WPF应用程序WrapWindow上动态加载大约7000个单词的字符串数组。文本应该是透明的,以暴露背后的图像(例如标签云)。我在示例中附加了链接,该链接将帮助您可视化问题。

我已经尝试过使用ImageBrush,但它不支持直接内容(即字符串)。我也尝试使用不透明蒙版,但没有成功。

为了给您一个想法,下面是指向SO上类似的未答复主题的链接,但具有Im试图实现的效果的确切图像。

transparent text with opaque background

欢迎提出任何想法。

谢谢

c# wpf xaml opacity mosaic
1个回答
0
投票

您可以使用文本轮廓的几何形状裁剪画布。这是一个将文本概述为形状的类。

public class OutlinedText : Shape
{
    public static readonly DependencyProperty TextProperty =
       DependencyProperty.Register(
       "Text",
       typeof(string),
       typeof(OutlinedText));

    private Geometry testGeometry;

    public OutlinedText()
    {
        FontFamily = new FontFamily("Arial");
        FontWeight = FontWeights.ExtraBold;
        FontStyle = FontStyles.Normal;
        this.FontSize = 14;
    }

    public FontFamily FontFamily { get; set; }

    public int FontSize { get; set; }

    public FontStyle FontStyle { get; set; }

    public FontWeight FontWeight { get; set; }

    public Point Origin { get; private set; }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { this.SetValue(TextProperty, value); }
    }

    protected override Geometry DefiningGeometry => this.testGeometry ?? Geometry.Empty;

    public static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => ((OutlinedText)d).CreateTextGeometry();

    protected override Size MeasureOverride(Size availableSize)
    {
        if (this.testGeometry == null)
        {
            this.CreateTextGeometry();
        }

        if (this.testGeometry.Bounds == Rect.Empty)
        {
            return new Size(0, 0);
        }

        return new Size(Math.Min(availableSize.Width, this.testGeometry.Bounds.Width), Math.Min(availableSize.Height, this.testGeometry.Bounds.Height));
    }

    private void CreateTextGeometry()
    {
        var formattedText = new FormattedText(
            this.Text,
            Thread.CurrentThread.CurrentUICulture,
            FlowDirection.LeftToRight,
            new Typeface(FontFamily, FontStyle, FontWeight, FontStretches.Normal),
            this.FontSize,
            Brushes.Black);
        this.testGeometry = formattedText.BuildGeometry(this.Origin);
    }
}

照常在xaml中使用

<local:OutlinedText
        Fill="Transparent"
        FontSize="16"
        Stroke="Black"
        StrokeThickness="1"
        Text="Test text"
        Visibility="Visible" />

因此,如果您有一个白色背景的画布,则可以使用文本路径的反面对其进行裁剪。要反转剪辑,请创建一个路径,该路径将文本的路径几何形状与与画布相同尺寸的矩形相结合。使用“排除”的组合几何模式。

 <Canvas
        x:Name="canvas"
        Background="White"
        Clip="{Binding ElementName=path, Path=RenderedGeometry}" />

    <Path Name="path" Fill="White">
        <Path.Data>
            <CombinedGeometry
                Geometry1="{Binding ElementName=rect, Path=RenderedGeometry}"
                Geometry2="{Binding ElementName=ot, Path=RenderedGeometry}"
                GeometryCombineMode="Exclude" />
        </Path.Data>
    </Path>
    <local:OutlinedText
        x:Name="ot"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Panel.ZIndex="1"
        Fill="Red"
        FontSize="16"
        Stroke="Black"
        StrokeThickness="1"
        Text="Test text"
        Visibility="Hidden" />
    <Rectangle
        x:Name="rect"
        Width="{Binding ElementName=canvas, Path=ActualWidth}"
        Height="{Binding ElementName=canvas, Path=ActualHeight}" />
© www.soinside.com 2019 - 2024. All rights reserved.