在 WPF 中使用另一个控件作为不透明蒙版?

Posted

技术标签:

【中文标题】在 WPF 中使用另一个控件作为不透明蒙版?【英文标题】:Use another control as an opacity mask in WPF? 【发布时间】:2010-11-17 01:26:56 【问题描述】:

我正在尝试将 OpacityMask 属性与 VisualBrush 结合使用,以便当您将图像拖到另一个控件(例如另一个图像、矩形或任何其他控件)上时,图像的第二个部分控件具有不同的不透明度。也就是说,图像具有一些非零的基本不透明度,并且位于另一个控件上方的图像的任何部分都具有不同的(同样,非零)不透明度。

这可以简单地使用 VisualBrush 和 OpacityMask 吗?还是需要更复杂的方法?

谢谢!

编辑:我正在尝试使图像具有较低的不透明度(例如 0.5),并且被拖动到控件上方的部分具有更高的不透明度(例如 1.0)。我最初忽略了这个细节,这对所采取的方法很重要。

【问题讨论】:

我的想法是使用一个图像或形状,该图像或形状的形状与控件的形状相同,并且在您移动对象时会弄乱 OpacityMask 的偏移量,但这通常不会是很好的解决方案,特别是如果您想用作掩码的控件是动态的(在我的情况下不是)。 我忘了提到它通常不是一个好的解决方案的原因是因为如果你想要图像上的某种基本不透明度(我愿意),你必须制作那个图像将控件“伪造”得很大(以适应大偏移量或大的可蒙版图像)。 你刚刚获得了 34 代表,你是如何开始 150 代表赏金的? 当您开始赏金时,代表会立即从您身上移除(并且他们会在您提供的任何内容中添加 50)。在赏金之前我还有更多。 【参考方案1】: 没有面具 为控件定义视觉画笔 使用画笔在控件顶部绘制形状 在形状和控件之间拖动图像 设置画笔的不透明度以达到所需的效果

【讨论】:

我还没有尝试过这个,但如果我想对控件有一个较低的不透明度,这似乎会很棒。如果我想要更高的不透明度(即图像的不透明度 = 0.5,而控件上方的部分不透明度 = 1.0)怎么办?我认为这种方法只能降低图像的不透明度,而不能增加它。如果我错了,请纠正我。谢谢。 :) 我注意到我最初没有在我的问题中指定此要求。我已编辑问题以包含此内容。【参考方案2】:

除了 ima 的回答之外,我还使用不透明蒙版解决了这个问题。我使用以下代码挂钩到图像的 LayoutUpdated 事件。

// Make a visual brush out of the masking control.
VisualBrush brush = new VisualBrush(maskingControl);
// Set desired opacity.
brush.Opacity = 1.0;
// Get the offset between the two controls.
Point offset = controlBeingMasked.TranslatePoint(new Point(0, 0), maskingControl);
// Determine the difference in scaling.
Point scale = new Point(maskingControl.ActualWidth / controlBeingMasked.ActualWidth, 
    maskingControl.ActualHeight / controlBeingMasked.ActualHeight);
TransformGroup group = new TransformGroup();
// Set the scale of the mask.
group.Children.Add(new ScaleTransform(scale.X, scale.Y, 0, 0));
// Translate the mask so that it always stays in place.
group.Children.Add(new TranslateTransform(-offset.X, -offset.Y));
// Rotate it by the reverse of the control, to keep it oriented correctly.
// (I am using a ScatterViewItem, which exposes an ActualOrientation property)
group.Children.Add(new RotateTransform(-controlBeingMasked.ActualOrientation, 0, 0));
brush.Transform = group;
controlBeingMasked.OpacityMask = brush;

如果您想要一个所需的基本不透明度,请使用两个图像;一个始终处于基本不透明度,另一个使用位于其顶部的不透明度蒙版。如果您希望基本不透明度高于蒙版不透明度,那么使用 ima 的方法可能更容易。

与无遮罩方法相比,此解决方案的一个优点是,如果遮罩控件移动、更改大小等,它将自动获取更改,而无需保持另一个控件与之同步。

它的外观如下: (来源:yfrog.com)

【讨论】:

正如我提到的,如果你想要基本不透明度 > 蒙版不透明度,我不相信你可以使用这种方法,因为它使用两个图像,你只能添加不透明度,不能减去它。 ima建议的方法可能最适合基本不透明度>蒙面不透明度。但我相信我的解决方案是逆向操作的好方法。

以上是关于在 WPF 中使用另一个控件作为不透明蒙版?的主要内容,如果未能解决你的问题,请参考以下文章

在WPF中使用另一个控件作为不透明蒙板?

iphone:如何在 UIVIEW 上制作透明蒙版

如何覆盖 WPF 中父控件的不透明度?

设置 WPF 标签内容 Alpha 透明度而不是整个控件的不透明度

如何在视频控件上方添加透明控件,例如在 mediaelement 上的 wpf 标签

WPF:如何使用透明画布和可点击子项制作覆盖控件