WPF:圆角图片

16
<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Background="Black">
    <!-- Rounded yellow border -->
    <Border BorderThickness="3" BorderBrush="Yellow" CornerRadius="10" Padding="2"
        HorizontalAlignment="Center" VerticalAlignment="Center">
      <Grid>
         <!-- Rounded mask (stretches to fill Grid) -->
         <Border Name="mask" Background="White" CornerRadius="7"/>
         <!-- Main content container -->
         <StackPanel>
             <!-- Use a VisualBrush of 'mask' as the opacity mask -->
             <StackPanel.OpacityMask>
                 <VisualBrush Visual="{Binding ElementName=mask}"/>
             </StackPanel.OpacityMask>
             <!-- Any content -->
             <Image Source="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg"/>
             <Rectangle Height="50" Fill="Red"/>
             <Rectangle Height="50" Fill="White"/>
             <Rectangle Height="50" Fill="Blue"/>
         </StackPanel>
      </Grid>
    </Border>
</Page>

这段 XAML 代码来自WPF - 为任何元素实现简单圆角,但是它对我不起作用 =(

<Border Canvas.Left="55"
        Canvas.Top="30"
        Width="100"
        Height="Auto"
        Margin="12,12,8,0"
        VerticalAlignment="Top"
        BorderBrush="#FF3B5998"
        BorderThickness=".5"
        CornerRadius="18">
    <Border.Effect>
        <DropShadowEffect BlurRadius="5"
                          Opacity=".5"
                          ShadowDepth="3" />
    </Border.Effect>
    <Border Name="ReceiverColor"
            BorderBrush="#FF96B2E4"
            BorderThickness="6"
            CornerRadius="15">
        <Border Name="Mask"
                BorderBrush="#FF3B5998"
                BorderThickness=".5"
                CornerRadius="13">
                <StackPanel>
                    <StackPanel.OpacityMask>
                        <VisualBrush Visual="{Binding ElementName=Mask}" />
                    </StackPanel.OpacityMask>
                    <Image Name="Receiver" />
                </StackPanel>
        </Border>
    </Border>
</Border>

--- 编辑 ---
我将边框大小设为自适应,将图片源更改为来自链接的图片。
当窗口加载时,边框大小变为图片大小,但是图片没有显示!

6个回答

44
你可以定义一个 <Border/> 元素,将它的 <Border.Background/> 属性设置为一个 <ImageBrush/>,设置该边框的 CornerRadius 属性,然后你就完成了!
<Border CornerRadius="8,0,8,0">
    <Border.Background>
        <ImageBrush Stretch="Fill" ImageSource="ImageSource"/>
    </Border.Background>
</Border>

27

你忘记了将遮罩和图片作为兄弟元素放置在网格中,并将图片嵌套在遮罩内。而且你还忘记设置遮罩的背景。

以下是正确的代码:

<Grid>
    <Border Canvas.Left="55"
            Canvas.Top="30"
            Width="100"
            Height="Auto"
            Margin="12,12,8,0"
            VerticalAlignment="Top"
            BorderBrush="#FF3B5998"
            BorderThickness=".5"
            CornerRadius="18">
        <Border.Effect>
            <DropShadowEffect BlurRadius="5"
                              Opacity=".5"
                              ShadowDepth="3" />
        </Border.Effect>
        <Border Name="ReceiverColor"
                BorderBrush="#FF96B2E4"
                BorderThickness="6"
                CornerRadius="15">
            <Grid>
                <Border Name="Mask"
                        Background="White"
                        BorderBrush="#FF3B5998"
                        BorderThickness=".5"
                        CornerRadius="13">
                </Border>
                <StackPanel>
                    <Image Name="Receiver"
                           Source="/Images/test.jpg" />
                    <StackPanel.OpacityMask>
                        <VisualBrush Visual="{Binding ElementName=Mask}" />
                    </StackPanel.OpacityMask>
                </StackPanel>
            </Grid>
        </Border>
    </Border>
</Grid>

不是第一段代码来自文章,而是第二段代码来自我的项目。 - Ahmed Ghoneim

12

在WPF中,这个对我有效。

    <Ellipse Width="50" Height="50">
        <Ellipse.Fill>
            <ImageBrush ImageSource="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg" />
        </Ellipse.Fill>
     </Ellipse>

这个解决方案无法控制实际半径,也失去了对实际图像的控制。如果你需要一个椭圆形,那么这是一个好的解决方案 - 但这与问题所要求的圆角不同。 - Anthony Nichols

5

以上所有答案对我来说都没有完全起作用。我试图在可调整大小且具有以下属性的图像上实现圆角:Stretch="UniformToFill"VerticalAlignment="Center"HorizontalAlignment="Center"

当图像被调整大小时,居中对齐会使中间部分被裁剪,而底部和右侧被裁剪。使用图像画刷的解决方案可以工作,但我在保持内容在中心裁剪方面遇到了问题。

标记的答案对于非矩形透明图像存在问题,因为“掩模”边框最终将显示为白色背景。以下是对我有效的实现:

<Grid>
    <WrapPanel Name ="container">
        <Image Source="sample_image.png" VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="UniformToFill"/>
        <WrapPanel.OpacityMask>
            <VisualBrush >
                <VisualBrush.Visual>
                    <Border Height="{Binding ElementName=container, Path=ActualHeight}" 
                            Width="{Binding ElementName=container, Path=ActualWidth}"
                            Background="White" CornerRadius="15" />
                </VisualBrush.Visual>
            </VisualBrush>
        </WrapPanel.OpacityMask>
    </WrapPanel>
</Grid>

此解决方案允许定义最大宽度和最大高度。 - user2019716
很棒的解决方案!只有一件小事,外部Grid父级不是必需的。 - stoj

2

您可以像Usman Ali提到的那样使用椭圆(我自己也想到了这个方法,不是从他那里学来的)。

非常简单,先用所需属性创建一个椭圆,然后在XAML中将填充设置为带有所需图像的imagebrush:

<Ellipse Height="Auto" Width="100">
    <Ellipse.Fill>
        <ImageBrush ImageSource="YOUR IMAGE SOURCE/LINK HERE"/>
    </Ellipse.Fill>
</Ellipse>

如果您想在C#中执行某些操作:

Ellipse YourEllipseName = new Ellipse
{
    Height = 50,
    Width = 50,
    StrokeThickness = 0,
    Fill = new ImageBrush
    {
        Stretch = Stretch.Uniform,
        ImageSource = new BitmapImage(new Uri("YOUR IMAGE SOURCE HERE"))
    }
};

1
<Grid Background="Black">
<Rectangle RadiusX="20" RadiusY="20"
Width="130"
Height="130">
<Rectangle.Fill>
<ImageBrush x:Name="myImage" ImageSource="C:\Path\Desktop\visual-studio-2010-logo.png"/>
</Rectangle.Fill>
</Rectangle>
</Grid>

1
通常情况下,如果答案包含代码的意图和解决问题的原因,而不会引入其他问题,那么这些答案会更有帮助。 - Tim Diekmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接