在已调整大小的图像上叠加多个矩形

时间:2014-01-29 01:23:35

标签: c# wpf image xaml rectangles

我是WPF的新手,我尝试使用在每张图片中的面上绘制的矩形来可视化图像。 我有关于每个图像中每个矩形的宽度,高度,左上角X和Y坐标(以原始图像为单位)的信息。

我的C#:

public class FaceRectangle
{
    Rectangle rect;        

    public FaceRectangle(int topX, int topY, int width, int height)
    {
        rect = new Rectangle(topX, topY, width, height);
    }
    public int X { get { return rect.X; } }
    public int Y { get { return rect.Y; } }
    public int Width { get { return rect.Width; } }
    public int Height { get { return rect.Height; } }
    ...
 }

public class Photo
{
    public BitmapImage Img { get; set; }
    public string Filename { get; private set; }

    public ObservableCollection<FaceRectangle> Faces { get; private set; }
    ...
}

public class PhotoCollection : ObservableCollection<Photo>
{
 ...
}

在查看相关问题之后,这就是我的XAML - 但是我在图像上覆盖矩形并调整它们的大小和位置以匹配图像时遇到了麻烦。我该如何实现这个目标呢?

更新XAML

<Window x:Class="TempFaceViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:er="clr-namespace:TempFaceViewer"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=System">

<Window.Resources>
    <Style TargetType="{x:Type ListBoxItem}" x:Key="ImageListItem">
        <Style.Resources>
            <!-- Background of selected item when focussed -->
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Gray" />
        </Style.Resources>
    </Style>

    <!-- Main photo catalog view -->
    <Style TargetType="{x:Type ListBox}" x:Key="PhotoListBoxStyle">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}" >
                    <WrapPanel Margin="5" IsItemsHost="True" Orientation="Horizontal" 
                   ItemHeight="95" 
                   ItemWidth="95" 
                   VerticalAlignment="Top" HorizontalAlignment="Stretch" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- Image Template -->
    <DataTemplate DataType="{x:Type er:Photo}">
        <Grid VerticalAlignment="Center" HorizontalAlignment="Center" Margin="6">
            <!-- Drop Shadow -->
            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="4" Background="#44000000">
                <Border.RenderTransform>
                    <TranslateTransform X="5" Y="5" />
                </Border.RenderTransform>
                <Border.BitmapEffect>
                    <BlurBitmapEffect Radius="8" />
                </Border.BitmapEffect>
            </Border>
            <!-- Image Template -->
            <Border Padding="4" Background="White" BorderBrush="#22000000" BorderThickness="1">
                <Image Source="{Binding Img}" />
            </Border>
        </Grid>
    </DataTemplate>
</Window.Resources>

<Grid DataContext="{Binding Source={StaticResource Photos}}">
    <Grid.RowDefinitions>
        <RowDefinition Height="100*" />
        <RowDefinition Height="100*" />
    </Grid.RowDefinitions>

    <DockPanel Grid.Column="0" Grid.Row="0" Margin="0,0,0,10" Height="160">

            <ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
                <ListBox 
                IsSynchronizedWithCurrentItem="True"
                Name="PhotosListBox" 
                Style="{StaticResource PhotoListBoxStyle}" 
                Margin="5" 
                SelectionMode="Extended" 
                ItemsSource="{Binding}" 
                SelectedIndex="0" 
                ItemContainerStyle="{StaticResource ImageListItem}"                   
                >
                </ListBox>
            </ScrollViewer>

    </DockPanel>

    <Viewbox Grid.Column="0" Grid.Row="1">
        <Grid>
            <Image Source="{Binding Img}" />
            <ItemsControl ItemsSource="{Binding Faces}" HorizontalAlignment="Left" VerticalAlignment="Top">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas IsItemsHost="True" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="er:FaceRectangle">
                        <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Red" StrokeThickness="1" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemContainerStyle>
                    <Style>
                        <Setter Property="Canvas.Left" Value="{Binding X}" />
                        <Setter Property="Canvas.Top" Value="{Binding Y}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </Grid>
    </Viewbox>

</Grid>
</Window>

谢谢!

1 个答案:

答案 0 :(得分:0)

在ItemContainerStyle中设置画布的顶部/左侧属性,并将背景图像和ItemsControl放在网格中,以便它们重叠,对齐并使用相同的比例(像素)。如果您将此网格包装在ViewBox中,则所有内容都将根据需要缩放:

<Viewbox>
    <Grid>
        <Image Source="{Binding Img}" />
        <ItemsControl ItemsSource="{Binding Faces}" HorizontalAlignment="Left" VerticalAlignment="Top">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="er:FaceRectangle">
                    <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Red" StrokeThickness="1" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Canvas.Left" Value="{Binding X}" />
                    <Setter Property="Canvas.Top" Value="{Binding Y}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>
    </Grid>
</Viewbox>

更新:您必须在页面上发布任何其他代码。我已经尝试将它放在网格中,如你所描述的那样工作正常,除了这个之外,我的窗口中没有别的东西:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100*" />
        <RowDefinition Height="100*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100*" />
        <ColumnDefinition Width="100*" />
    </Grid.ColumnDefinitions>
    <Viewbox Grid.Column="0" Grid.Row="1">
        <Grid>
            <Image Source="{Binding Img}" />
            <ItemsControl ItemsSource="{Binding Faces}" HorizontalAlignment="Left" VerticalAlignment="Top">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas IsItemsHost="True" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="er:FaceRectangle">
                        <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Red" StrokeThickness="1" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemContainerStyle>
                    <Style>
                        <Setter Property="Canvas.Left" Value="{Binding X}" />
                        <Setter Property="Canvas.Top" Value="{Binding Y}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </Grid>
    </Viewbox>
</Grid>

我怀疑你在其他地方(即Styles,DataTemplates等)有更改默认行为的资源,尝试在一个独立的应用程序中运行我的代码。