c# - 从边框中排除标签文本

标签 c# wpf label border

我有一个顶部带有文本的银色边框,我想将其排除(将文本从边框上切开)以透视边框后面的背景,并应用了投影位图效果。 这是否可能,无需使用 Photoshop 来创建基本上做同样事情但不那么灵活的图像?

如果可能的话,我将如何着手完成这样的任务?

最佳答案

我试了一下,结果如下。
棘手的部分是“反转”边框的 OpacityMask。我创建了一个派生自 Image 的类,它添加了一些依赖属性,如 Text、FontFamily 和 EmSize。然后它使用 this link 中的方法将文本转换为几何图形。 .

您可以尝试使用 Text、FontFamily、EmSize、Width 和 Height,直到获得所需的结果。您当然也可以向 InvertOpacityText 添加额外的 DP 以增加灵 active 。

我最终得到了这个

alt text

<Grid Background="Blue">
    <Border Background="Gray" CornerRadius="8,8,8,8" Width="240" Height="220">
        <Border.Effect>
            <DropShadowEffect ShadowDepth="10"
                              Direction="310"
                              Color="Black"
                              Opacity="0.8"
                              BlurRadius="4"/>
        </Border.Effect>
        <Border.OpacityMask>
            <VisualBrush>
                <VisualBrush.Visual>
                    <local:InvertOpacityText Text=" Now Playing"
                                             EmSize="70"
                                             Stretch="Fill"
                                             Width="510"
                                             Height="414"
                                             FontFamily="Broadway">
                        <local:InvertOpacityText.LayoutTransform>
                            <RotateTransform Angle="-90"/>
                        </local:InvertOpacityText.LayoutTransform>
                    </local:InvertOpacityText>
                </VisualBrush.Visual>
            </VisualBrush>
        </Border.OpacityMask>
        <Image Margin="45,5,5,5" Source="C:\PhilCollins.png"/>
    </Border>
</Grid>

InvertOpacityText.cs

public class InvertOpacityText : Image
{
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text",
                                    typeof(string),
                                    typeof(InvertOpacityText),
                                    new FrameworkPropertyMetadata(string.Empty,
                                                                  TargetPropertyChanged));
    public static readonly DependencyProperty EmSizeProperty =
        DependencyProperty.Register("EmSize",
                                    typeof(double),
                                    typeof(InvertOpacityText),
                                    new FrameworkPropertyMetadata(70.0,
                                                                  TargetPropertyChanged));
    public static readonly DependencyProperty FontFamilyProperty =
        DependencyProperty.Register("FontFamily",
                                    typeof(FontFamily),
                                    typeof(InvertOpacityText),
                                    new FrameworkPropertyMetadata(new FontFamily(),
                                                                  TargetPropertyChanged));

    private static void TargetPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        InvertOpacityText invertOpacityText = (InvertOpacityText)source;
        invertOpacityText.OnTextChanged();
    }

    public string Text
    {
        get { return (string)base.GetValue(TextProperty); }
        set { base.SetValue(TextProperty, value); }
    }
    public double EmSize
    {
        get { return (double)base.GetValue(EmSizeProperty); }
        set { base.SetValue(EmSizeProperty, value); }
    }
    public FontFamily FontFamily
    {
        get { return (FontFamily)base.GetValue(FontFamilyProperty); }
        set { base.SetValue(FontFamilyProperty, value); }
    }

    private void OnTextChanged()
    {
        if (Source == null)
        {
            Source = CreateBitmapSource();
        }

        FormattedText tx = new FormattedText(Text,
                                             Thread.CurrentThread.CurrentUICulture,
                                             FlowDirection.LeftToRight,
                                             new Typeface(FontFamily,
                                                          FontStyles.Normal,
                                                          FontWeights.Bold,
                                                          FontStretches.Normal),
                                             EmSize,
                                             Brushes.Black);
        Geometry textGeom = tx.BuildGeometry(new Point(0, 0));
        Rect boundingRect = new Rect(new Point(-100000, -100000), new Point(100000, 100000));
        RectangleGeometry boundingGeom = new RectangleGeometry(boundingRect);
        GeometryGroup group = new GeometryGroup();
        group.Children.Add(boundingGeom);
        group.Children.Add(textGeom);
        Clip = group;
    }
    private BitmapSource CreateBitmapSource()
    {
        int width = 128;
        int height = width;
        int stride = width / 8;
        byte[] pixels = new byte[height * stride];
        List<System.Windows.Media.Color> colors = new List<System.Windows.Media.Color>();
        colors.Add(System.Windows.Media.Colors.Red);
        colors.Add(System.Windows.Media.Colors.Blue);
        colors.Add(System.Windows.Media.Colors.Green);
        BitmapPalette myPalette = new BitmapPalette(colors);
        return BitmapSource.Create(width,
                                   height,
                                   96,
                                   96,
                                   PixelFormats.Indexed1,
                                   myPalette,
                                   pixels,
                                   stride);
    }
}

关于c# - 从边框中排除标签文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4559748/

相关文章:

c# - 从 WPF C# 中的 For 循环调用用户定义的函数

c# - 当某些条件为 True 时,对 WPF 中的数据网格单元格进行动画处理?

c# - 使用 EF 的单例设计模式和异步方法

c# - 为什么假!=假?

python-3.x - Matplotlib:极坐标轴刻度标签位置

MATLAB 在绘图旁边显示图例标签

c# - 值来自 C# 到 Javascript 的形式

c# - 如果两个库具有完全相同的类怎么办?

c# - 如何获取位置(亲和区域)或名称集群(结构服务)

C# XML 反序列化。将节点中的所有内部文本读入字符串属性