图像超出边界的圆角边界的裁剪内容

时间:2021-05-07 09:21:48

标签: c# wpf xaml .net-4.5

我需要在圆形边框外移动和旋转图像

示例: enter image description here

How to make the contents of a round-cornered border be also round-cornered?中找到答案:

<Grid>
    <Grid.OpacityMask>
        <VisualBrush Visual="{Binding ElementName=Border1}" />
    </Grid.OpacityMask>
    <Border x:Name="Border1" CornerRadius="30" Background="Green" />
    <TextBlock Text="asdas das d asd a sd a sda" />
</Grid>

如果元素没有越界,这会起作用。

如果像这样使用旋转和/或边距:

<Grid>
    <Grid.OpacityMask>
        <VisualBrush Visual="{Binding ElementName=_border1}" />
    </Grid.OpacityMask>
    <Border x:Name="_border1"
            BorderThickness="0"
            CornerRadius="30"
            Background="Green" />
    <TextBlock Text="SomeText"
               Foreground="Yellow" />
    <Image Source="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
           Margin="-5 0 0 0"
           Height="20"
           Width="55"
           Stretch="UniformToFill"
           VerticalAlignment="Top"
           HorizontalAlignment="Left"
           RenderTransformOrigin="0.5 0.5">
        <Image.RenderTransform>
            <RotateTransform Angle="-7" />
        </Image.RenderTransform>
    </Image>
</Grid>

舍入被置换

enter image description here

如何像第一个示例中那样裁剪图像?感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

VisualBrush 的视口计算出现问题。不确定这是否是 WPF 中的错误。

解决方法可能是以绝对单位设置视口,使用矩形而不是边框​​:

<Grid.OpacityMask>
    <VisualBrush
        Visual="{Binding ElementName=rect}"
        ViewportUnits="Absolute"
        Viewport="{Binding ElementName=rect, Path=RenderedGeometry.Rect}"/>
</Grid.OpacityMask>
<Rectangle x:Name="rect" RadiusX="30" RadiusY="30" Fill="Green"/>

或者更简单,设置 Clip 属性而不是 OpacityMask,但仍然支持调整大小:

<Grid Clip="{Binding ElementName=rect, Path=RenderedGeometry}">
    <Rectangle RadiusX="30" RadiusY="30" Fill="Green" x:Name="rect"/>
    ...
</Grid>

答案 1 :(得分:1)

我设法使用 Clip 而不是 OpacityMask 达到了预期的结果。那么所有需要裁剪的元素都必须是 Border 的子元素。如果您的 Border 需要是动态的,您需要使用 RectangleGeometryBorder 的维度绑定到 Converter 的维度。

<Grid>
    <Border BorderThickness="0"
            CornerRadius="30"
            Background="Green">
        <Border.Clip>
            <RectangleGeometry RadiusX="30" RadiusY="30" Rect="0,0,500,400"/>
        </Border.Clip>
        <Grid>
            <TextBlock Text="SomeText"
                       Foreground="Yellow"/>
            <Image Source="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
                   Margin="-5 0 0 0"
                   Height="20"
                   Width="55"
                   Stretch="UniformToFill"
                   VerticalAlignment="Top"
                   HorizontalAlignment="Left"
                   RenderTransformOrigin="0.5 0.5">
                <Image.RenderTransform>
                    <RotateTransform Angle="-7"/>
                </Image.RenderTransform>
            </Image>
        </Grid>
    </Border>
</Grid>

Clipping works!

Clipping works!