带定心和剪裁的WPF图像主机

带定心和剪裁的WPF图像主机,wpf,image,xaml,image-clipping,Wpf,Image,Xaml,Image Clipping,我觉得我可能需要一些转换器,但这就是我想要做的。我想要一个具有以下参数的单个图像控件(因为它位于绑定到真实数据的数据模板中) 在90x90(无任何拉伸)的空间中居中 具有半径为40像素的圆形剪裁(水平和垂直) 如果图像>90x90,它应该在90x90空间内居中,并从中间剪辑一个40x40的圆 如果图像90x90的图像,剪裁工作正常,但图像未居中。对于

我觉得我可能需要一些转换器,但这就是我想要做的。我想要一个具有以下参数的单个图像控件(因为它位于绑定到真实数据的数据模板中)

  • 在90x90(无任何拉伸)的空间中居中
  • 具有半径为40像素的圆形剪裁(水平和垂直)
  • 如果图像>90x90,它应该在90x90空间内居中,并从中间剪辑一个40x40的圆
  • 如果图像<90x90,则应在90x90空间内居中。由于整个图像都包含在剪辑区域内,因此剪辑圆应该没有效果
下面是我的XAML代码。对于精确为90x90的图片(即,它们不会拉伸,它们会使图像居中,剪辑也会起作用),这与预期一样有效。对于>90x90的图像,剪裁工作正常,但图像未居中。对于<90x90的图像,图像居中,但剪辑似乎将图像放置在图像内容的左上角区域,因此,剪辑将剪辑图像的左上角部分

<Style x:Key="ImageStyle">
    <Setter Property="Width" Value="90" />
    <Setter Property="Height" Value="90" />
    <Setter Property="Stretch" Value="None" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="Clip">
        <Setter.Value>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Setter.Value>
    </Setter>
</Style>

<Grid>
    <!-- Other Stuff -->
    <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
</Grid>

我可以通过在网格中换行并将剪辑移动到网格中来解决第二个问题(小图像剪辑),但大的东西不会居中:

<Grid>
    <!-- Other Stuff -->
    <Grid Width="90" Height="90">
        <Grid.Clip>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Grid.Clip>
        <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
    </Grid>
</Grid>

在数据模板中使用ImageBrush。然后可以绘制成椭圆,而不使用剪裁

XAML

  <Grid>
    <ListBox ItemsSource='{Binding}'>
      <ListBox.ItemTemplate>
        <DataTemplate>

          <Grid Width='90' Height='90' Background='Yellow'>

          <Ellipse Width='40'
                   Height='40'>
            <Ellipse.Fill>
              <ImageBrush ImageSource='{Binding ImagePath}'
                          Stretch='None' />
            </Ellipse.Fill>

          </Ellipse>
          </Grid>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>

代码

公共部分类窗口4:窗口{
公共窗口4(){
初始化组件();
var data=新列表();
添加(新解调数据{Header=“Large Image”,ImagePath=“flower.png”});
添加(新解调数据{Header=“Medium Image”,ImagePath=“flower\u med.png”});
添加(新解调数据{Header=“Small Image”,ImagePath=“flower\u Small.png”});
this.DataContext=数据;
}
}
内部类解调器{
公共字符串头{get;set;}
公共字符串ImagePath{get;set;}
}
结果


我最后不得不从图像样式中删除宽度和高度属性。使用WPF Snoop查看图像时,图像现在比包含的网格大,但由于网格具有固定的大小,因此它将自身集中在该网格上

<Style x:Key="ImageStyle">
    <Setter Property="Stretch" Value="None" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
</Style>

<Grid>
    <!-- Other Stuff -->
    <Grid Width="90" Height="90">
        <Grid.Clip>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Grid.Clip>
        <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
    </Grid>
</Grid>

我找到的居中剪裁图像的最简单方法是使用不同的元素,例如矩形,然后用ImageBrush填充它。例如:

<Rectangle>
    <Rectangle.Fill>
        <ImageBrush
            ImageSource="{Binding SomeUriPropertyOrOther}"
            Stretch="UniformToFill"/>
    </Rectangle.Fill>
</Rectangle>


这不需要定心和剪裁。(与拉伸无关==填充和均匀,我想。)

谢谢你这么好的解决方案谢谢!这有帮助
<Rectangle>
    <Rectangle.Fill>
        <ImageBrush
            ImageSource="{Binding SomeUriPropertyOrOther}"
            Stretch="UniformToFill"/>
    </Rectangle.Fill>
</Rectangle>