简体   繁体   English

在调整大小的图像上覆盖多个矩形

[英]Overlay multiple rectangles on a resized image

I'm new to WPF and I'm trying to visualize images with rectangles drawn over the faces in each image. 我是WPF的新手,我试图通过在每个图像的面孔上绘制矩形的可视化图像。 I have information about the width, height, top left X and Y co-ordinates (in pixels wrt the original image) of each rectangle in each image. 我有关于每个图像中每个矩形的宽度,高度,左上角X和Y坐标(以原始图像的像素为单位)的信息。

My C#: 我的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>
{
 ...
}

After looking through related questions, this is the XAML I have - but I'm having trouble overlaying the rectangles on the image and adjusting their size and posiiton to match the image. 看完相关问题后,这就是我所拥有的XAML,但是我无法在图像上覆盖矩形并调整其大小和位置以匹配图像。 How should I go about achieving this? 我应该如何实现这一目标?

UPDATED 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>

Thanks! 谢谢!

Set your canvas top/left properties in ItemContainerStyle instead and put both the background image and the ItemsControl in a Grid so that they're overlapping, aligned and using the same scale (pixels). 而是在ItemContainerStyle中设置画布的上/左属性,然后将背景图像和ItemsControl置于Grid中,以便它们重叠,对齐并使用相同的比例(像素)。 If you wrap this grid in a ViewBox then everything will scale together as needed: 如果将此网格包装在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>

UPDATE: You'll have to post any other code on the page. 更新:您必须在页面上发布任何其他代码。 I've tried putting it in a grid as you describe and it works fine, there's nothing else in my window other than this: 我已经按照您的描述尝试将其放置在网格中,并且可以正常工作,除此以外,我的窗口中没有其他内容:

<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>

I suspect you've got resources elsewhere (ie Styles, DataTemplates etc) that are changing the default behavior, trying running my code in an isolated app. 我怀疑您在其他地方有资源(例如,样式,DataTemplates等)正在更改默认行为,尝试在隔离的应用程序中运行我的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM