繁体   English   中英

当 window 大小发生变化时,如何在装饰器上绘制一个矩形以与它绑定的 Image 元素一起缩放?

[英]How do I get a Rectangle drawn on an adorner to scale with the Image element its bound to when the window size is changed?

我正在使用在装饰器上绘制的矩形来标记图像上的感兴趣区域。 问题是,如果我调整 window 的大小,矩形不会改变大小。

我是 WPF 的新手,所以我做了很多研究,在谷歌上搜索了多个不同的搜索词。 实际上,我只是通过这种方式学习了装饰器,而且我已经做到了这一点,但是我在如何完成最后一件作品上遇到了障碍。 我知道我的问题是基于矩形的大小,但我不知道要捕获/寻找什么来调整它,因为 wpf 会在 Z05B8C74CBD96FBF2DE4C1A352702FFF4Z 上调整实际图像 object 的大小以调整其大小。

这是我正在测试的应用程序的 XAML。

<Window x:Class="TestingAdorners.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestingAdorners"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
        <Grid ClipToBounds="True">
            <AdornerDecorator>
                <Image Name="Btn" Source="nyan.png" Stretch="Uniform"/>
            </AdornerDecorator>
        </Grid>
</Window>

装饰器 class:

    class RoiAdorner : Adorner
    {
        public Rect rectangle = new Rect();
        public RoiAdorner(UIElement adornedElement) : base(adornedElement)
        {
            rectangle.Height = 30;
            rectangle.Width = 100;
            IsHitTestVisible = false;

        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            Pen pen = new Pen(Brushes.Green, 5);

            drawingContext.DrawRectangle(null, pen, rectangle);

        }
    }

和 Xaml.cs

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            AdornerLayer.GetAdornerLayer(Btn).Add(new RoiAdorner(Btn));

        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
        }
    }

期望的结果是矩形随图像 object 缩放,使其始终覆盖图像的相同区域。 问题是我不知道如何捕获缩放因子以在 window 调整大小时对其进行缩放。

更新:在考虑了 Frenchy 的建议后,我意识到答案很简单:“标准化你的坐标”

您只需像这样调整您的渲染方法:

class RoiAdorner : Adorner
{
    public double factorX = 0d;
    public double factorY = 0d;
    public Rect rectangle = new Rect();
    public RoiAdorner(UIElement adornedElement) : base(adornedElement)
    {

        rectangle.Height = 30;
        rectangle.Width = 100;
        IsHitTestVisible = false;

    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        if (factorY == 0)
            factorY =  rectangle.Height / AdornedElement.DesiredSize.Height;
        if (factorX == 0)
            factorX = rectangle.Width / AdornedElement.DesiredSize.Width;
        var r = new Rect(new Size(AdornedElement.DesiredSize.Width * factorX, AdornedElement.DesiredSize.Height * factorY));
        //Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
        drawingContext.DrawRectangle(null, new Pen(Brushes.Red, 5), r);

    }

this.AdornedElement.DesiredSize 为您提供图像的大小。

我将使用的方法是将图片和矩形渲染为同一事物。 然后那一件事被拉伸,缩放或其他。

一种方法是使用 DrawingImage。 绘图方法如果相当低级,则非常有效。

    <Grid ClipToBounds="True">
        <AdornerDecorator>
            <Image Name="img" Stretch="Uniform">
                <Image.Source>
                    <DrawingImage PresentationOptions:Freeze="True">
                        <DrawingImage.Drawing>
                            <DrawingGroup>
                                <ImageDrawing Rect="0,0,595,446" ImageSource="DSC00025.jpg"/>
                                <GeometryDrawing Brush="Green">
                                    <GeometryDrawing.Geometry>
                                        <RectangleGeometry Rect="0,0,100,30"  />
                                    </GeometryDrawing.Geometry>
                                </GeometryDrawing>
                            </DrawingGroup>
                        </DrawingImage.Drawing>
                    </DrawingImage>
                </Image.Source>
            </Image>
        </AdornerDecorator>
    </Grid>

另一种是使用视觉刷。 控件继承自视觉 - 这是更高级别的编码。

    <Grid ClipToBounds="True">
        <AdornerDecorator>
            <Rectangle Name="rec">
            <Rectangle.Fill>
                <VisualBrush Stretch="Uniform">
                    <VisualBrush.Visual>
                        <Grid Height="446" Width="595">
                            <Image Source="DSC00025.jpg" Stretch="Fill"/>
                            <Rectangle Height="30" Width="100" Fill="Green"
                                       VerticalAlignment="Top" HorizontalAlignment="Left"/>
                        </Grid>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Rectangle.Fill>
            </Rectangle>
        </AdornerDecorator>
    </Grid>

请注意,这两个都是快速而肮脏的插图,可以为您提供想法。 我从硬盘驱动器上随机挑选的图像大小为 446 * 595。您可以根据自己的要求计算大小或绑定或拉伸。

暂无
暂无

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

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