不透明蒙版忽略ClipToBounds为True

时间:2014-09-13 20:50:27

标签: c# wpf image graphics wpf-controls

我有一个“面具画布”,我正在努力用作我主画画布的OpacityMask的来源。

我的两个画布大小相同,但是当我开始在画布边框附近绘画时,我得到了一些意想不到的结果。

我创建了一个gif来说明我的问题: enter image description here

在gif中,我首先画了面具(黑色)。然后在另一个将OpacityMask绑定到蒙版画布的画布上,我开始用草纹理绘画。如果我在画布中绘画,它工作正常,但如果我靠近画布的边界,它会翻译并缩放绘画。

我认为当我靠近边缘时,绘画画布的尺寸会发生变化,从而使图像偏斜。我如何解决这个问题,我已经为两个画布设置了ClipToBounds =“True”。如何使遮罩画布与绘画画布成比例?

编辑 - 这是两幅画布背后的代码。 面具画布:

<ItemsControl Name="maskDataBinding" Background="Transparent" Panel.ZIndex="-1" ClipToBounds="True" Height="512" Width="512" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Background="Transparent"  
                        Height="512" 
                        Width="512" 
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center"
                        ClipToBounds="True">
                </Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding Name}"
                            Width="{Binding Width}"
                            Height="{Binding Height}"
                            Opacity="{Binding Opacity}">
                    <Image.RenderTransform>
                        <TransformGroup>
                            <TranslateTransform X="{Binding OffsetX}" Y="{Binding OffsetY}"/>
                            <RotateTransform CenterX="{Binding CenterX}" CenterY="{Binding CenterY}" Angle="{Binding Angle}"/>
                        </TransformGroup>
                    </Image.RenderTransform>
                </Image>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

绘画画布:

<!--Outer collection-->
<ItemsControl Name="canvasDataBinding"
            Focusable="True"
            HorizontalAlignment="Center" 
            Height="512"
            Width="512" 
            VerticalAlignment="Center" 
            ClipToBounds="True">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas MouseMove="Canvas_MouseMove"
                    MouseEnter="Canvas_MouseEnter"
                    MouseLeave="Canvas_MouseLeave"
                    MouseDown="Canvas_MouseDown"
                    MouseUp="Canvas_MouseUp"
                    Background="Transparent"
                    ClipToBounds="True">

            </Canvas>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>

            <!--nested collection-->
            <ItemsControl Height="512" Width="512" HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding ImageSource}" ClipToBounds="True">

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas Background="Transparent"  
                                Height="512" 
                                Width="512" 
                                HorizontalAlignment="Center" 
                                VerticalAlignment="Center"
                                ClipToBounds="True">
                            <Canvas.OpacityMask>
                                <VisualBrush Visual="{Binding ElementName=maskDataBinding}"/>
                            </Canvas.OpacityMask>
                        </Canvas>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding Name}"
                        Width="{Binding Width}"
                        Height="{Binding Height}"
                        Opacity="{Binding Opacity}">
                            <Image.RenderTransform>
                                <TransformGroup>
                                    <TranslateTransform X="{Binding OffsetX}" Y="{Binding OffsetY}"/>
                                    <RotateTransform CenterX="{Binding CenterX}" CenterY="{Binding CenterY}" Angle="{Binding Angle}"/>
                                </TransformGroup>
                            </Image.RenderTransform>
                        </Image>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我的画布画布实际上只是画布的集合(每个画布都用来模拟一个图层)。每个画布都有一组图像。您可以看到我将OpacityMask绑定到嵌套集合的画布中。

修改: 所以我的假设是正确的。当我靠近边界时,它会使图像倾斜,因为绘画画布的宽度增加(如果你靠近左/右边框)并且高度增加(如果你接近顶部/底部边框),那么蒙版会被拉伸。关于解决方案/解决方法的任何想法?

这是另一个GIF。我删除了不透明蒙版,所以现在我只是画在画布上。我还在绘画画布上设置了ClipToBounds = False。无论是ClipToBounds是false还是true,不透明蒙版都应用于此未剪切的绘画画布。
enter image description here

1 个答案:

答案 0 :(得分:0)

我明白了。我只需要将OpacityMask应用于画布的任何父级。 OpacityMask可以看到画布上的所有内容,即使是边界之外的东西(ClipToBounds设置为True或False也无关紧要)。 Canvas的父级(在我的例子中是实际的ItemsControl)除去了Canvas边界之外的任何信息,这就是为什么将掩码应用于父级工作。

<!--nested collection-->
<ItemsControl Height="512" Width="512" HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding ImageSource}" >

    <ItemsControl.ItemsPanel>

        <ItemsPanelTemplate>

            <Canvas Name="paintingCanvas"
                    Background="Transparent"  
                    Height="512" 
                    Width="512" 
                    HorizontalAlignment="Center" 
                    VerticalAlignment="Center"
                    ClipToBounds="True">
            </Canvas>
        </ItemsPanelTemplate>

    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding Name}"
        Width="{Binding Width}"
        Height="{Binding Height}"
        Opacity="{Binding Opacity}">
                <Image.RenderTransform>
                    <TransformGroup>
                        <TranslateTransform X="{Binding OffsetX}" Y="{Binding OffsetY}"/>
                        <RotateTransform CenterX="{Binding CenterX}" CenterY="{Binding CenterY}" Angle="{Binding Angle}"/>
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.OpacityMask>
        <VisualBrush Visual="{Binding ElementName=maskDataBinding}"/>
    </ItemsControl.OpacityMask>
</ItemsControl>