2014-04-16 60 views
1

是否可以(以及如何)调整用于在桌面上显示WPF窗体的混合模式?将WPF窗口与桌面混合

我有一个窗口作为整个屏幕的覆盖。这里的XAML:

<Window x:Class="RedGreenBarsWPF.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Red/Green Overlay" Topmost="True" Height="300" Width="525" AllowsTransparency="True" WindowStyle="None" Background="Transparent" WindowStartupLocation="Manual" IsHitTestVisible="False"> 
    <Canvas Name="canvas" /> 
</Window> 

它不能被点击,并且它得到调整并移动到覆盖整个屏幕窗口加载时。然后我画一些形状像这样在画布上:

System.Windows.Media.Brush red = new SolidColorBrush(System.Windows.Media.Color.FromArgb(200, 255, 0, 0)); 

System.Windows.Size s = new System.Windows.Size(System.Windows.SystemParameters.PrimaryScreenWidth, System.Windows.SystemParameters.PrimaryScreenHeight); 

int lines = 20; 
for (double i = 0; i < s.Width; i += s.Width/lines) 
{ 
    System.Windows.Shapes.Rectangle rect = new System.Windows.Shapes.Rectangle 
    { 
     Width = s.Width/lines, 
     Height = s.Height 
    }; 

    rect.Fill = red; 

    Canvas.SetTop(rect, 0); 
    Canvas.SetLeft(rect, i * 2); 
    canvas.Children.Add(rect); 
} 

这也正是它应该,但不是我想要的。下面是在Photoshop中进行可视化(我貌似“正常”):

enter image description here

我需要找出一种方法来使它看起来像右侧,那里的文本不点亮的红色方块由重叠的颜色。我已经搜索了高和低,虽然有库可以完成这与窗口内的元素,我需要混合模式扩展到整个桌面。如何才能做到这一点?

+0

什么是你的合并覆盖和底层图像的算法?左侧的图像具有一定透明度的红色部分,黑色和红色合并在一起,为您提供“轻松”的外观。右边的模拟似乎用红色代替全白色,但是单独留下黑色。这对二进制黑白图像工作正常,但是当文本不是黑色或背景不是白色时会发生什么? –

+0

我试图用这个自己做实验......我的想法是为了做这样的事情,你必须得到每个矩形中的像素数据,并且如果数据不完全是R = 200(或者其他您指定的红色值),则可以使该像素完全透明。所以红色会在完全白色的背景上显示为红色,但会使其他所有内容流血。然而,似乎没有使用WPF做这件事的好方法(至少我还没有得到它的权利..) – ryrich

+0

@JohnKoerner我没有使用任何种类的特定算法来绘制矩形,我只是添加它直接到画布。文本出现在它后面,因为alpha值设置为只有200(255是完全不透明的)。 – Scott

回答

1

您需要使用不同的混合功能。到目前为止,我相信你没有简单的解决方案;这已经被请求,但尚未被WPF支持。

这个other question也是关于对WPF画笔使用不同的混合函数。它还包含有关如何实现自定义混合(实际上是整个混合库)的相当不错(但很长)的教程的链接。

这些页面几乎包含每个页面上的源代码。您需要以下内容来构建它们:(引用).NET 3.5 SP1,DirectX SDK以及CodePlex上WPF Futures内容中的Shader Effects BuildTask和Templates。

我在这里复制链接:

编辑:要捕获桌面图像,您可以尝试使用简单的FrameworkElement,如Rectangle,具有透明背景(Transparent是笔刷)。然后,您可以使用RenderTargetBitmap类将其转换为ImageBrush。下面的代码片段,应该帮助您开始:

public Brush RectangleToBrush(Rectangle rect) 
{ 
    int w = (int)rect.ActualWidth; 
    int h = (int)rect.ActualHeight; 
    var rtb = new RenderTargetBitmap(w, h, 96d, 96d, PixelFormats.Default); 
    rtb.Render(rect); 

    ImageBrush brush = new ImageBrush(BitmapFrame.Create(rtb)); 

    return brush; 
} 

你或许可以把这个矩形在你的.xaml文件,使用一个网格,使其覆盖整个窗口:

<Window ...> 
    <Grid> 
     <Rectangle x:Name="DesktopCaptureRectangle"/> 
     <Grid> 
      <!-- Your controls here --> 
     </Grid> 
    </Grid> 
</Window> 

注意:我不确定这个解决方案是否具有良好的性能...

+0

看起来不错!有什么办法可以将桌面本身作为多输入着色器的输入? – Scott

+1

我编辑我的答案,有关如何做到这一点的想法...我没有实际测试它,所以我不知道它会工作,但你可以试试看。 – Benlitz

+0

我会给它一个机会,非常感谢! – Scott