简体   繁体   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?

I'm using a rectangle drawn on an adorner to mark a region of interest on an image.我正在使用在装饰器上绘制的矩形来标记图像上的感兴趣区域。 The issue is that if I resize the window, the rectangle doesn't change size.问题是,如果我调整 window 的大小,矩形不会改变大小。

I'm new to WPF, so I've done a bunch of research, googling what I can with multiple different search terms.我是 WPF 的新手,所以我做了很多研究,在谷歌上搜索了多个不同的搜索词。 I actually just learned adorners that way, and I've gotten this far on that, but I've hit a wall on how to finish this last piece.实际上,我只是通过这种方式学习了装饰器,而且我已经做到了这一点,但是我在如何完成最后一件作品上遇到了障碍。 I know that my problem is based in the size of the rectangle, but I don't know what to capture/look for to adjust it, since wpf resizes the actual image object on window resize, so there's no scale factor to look at.我知道我的问题是基于矩形的大小,但我不知道要捕获/寻找什么来调整它,因为 wpf 会在 Z05B8C74CBD96FBF2DE4C1A352702FFF4Z 上调整实际图像 object 的大小以调整其大小。

Here's the XAML for the application I'm testing things in.这是我正在测试的应用程序的 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>

The adorner class:装饰器 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);

        }
    }

And the Xaml.cs和 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)
        {
        }
    }

The desired result is that the rectangle scales with the image object so that it always covers the same region of the image.期望的结果是矩形随图像 object 缩放,使其始终覆盖图像的相同区域。 The problem is I don't know how to capture a scale factor to scale it up and down as the window resizes.问题是我不知道如何捕获缩放因子以在 window 调整大小时对其进行缩放。

Update: After thinking through Frenchy's suggestion I realized the answer is simply: "Normalize your coordinates"更新:在考虑了 Frenchy 的建议后,我意识到答案很简单:“标准化你的坐标”

you just adapt your render method like this:您只需像这样调整您的渲染方法:

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 gives you the size of image. this.AdornedElement.DesiredSize 为您提供图像的大小。

The approach I would use is to render the picture and rectangle to the same thing.我将使用的方法是将图片和矩形渲染为同一事物。 Then that one thing is stretched, scaled or whatever.然后那一件事被拉伸,缩放或其他。

One way to do this would be to use a DrawingImage.一种方法是使用 DrawingImage。 Drawing methods are extremely efficient if rather low level.绘图方法如果相当低级,则非常有效。

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

Another is with a visualbrush.另一种是使用视觉刷。 Controls inherit from visual - this is somewhat higher level coding.控件继承自视觉 - 这是更高级别的编码。

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

Note that both of these are quick and dirty illustrations to give you the idea.请注意,这两个都是快速而肮脏的插图,可以为您提供想法。 The image I picked at random off my hard drive is sized 446 * 595. You could calculate sizes or bind or stretch as suits your requirement best.我从硬盘驱动器上随机挑选的图像大小为 446 * 595。您可以根据自己的要求计算大小或绑定或拉伸。

暂无
暂无

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

相关问题 如何在 canvas 中的图像上获取绘制矩形的 position - How to get position of drawn rectangle on image in canvas 如何在窗口周围绘制矩形? (当我知道它的句柄时) - How to draw a Rectangle around the Window? (When I know its handle) C 中如何改变图像的大小和改变在图像特定部分的图片框内绘制的矩形的大小# - How to change the size of the image and change the size of the rectangle that was drawn inside the picture box on a specific part of the image in C # 如何选择已经绘制的矩形? - How do I select a Rectangle that's already been drawn? WPF-当控件从未在屏幕上绘制(用于屏幕截图)时,如何以编程方式允许控件找到所需的尺寸? - WPF - how can I programmatically allow a control to find its desired size when it is never drawn on the screen (for a screenshot)? 为什么在粘贴到 Excel 时图像显示的大小大于其实际大小,我如何才能使其以自然大小显示? - Why does an image display at greater that its actual size when pasting into Excel, and how can I get it to display at its natural size? 更改表单大小后,如何自动调整控件的大小? - How do I resize the controls automatically when form size is changed? 在ViewModel(wpf)中通过均匀填充结构改变图像大小时如何绘制图像 - How to draw on an image when its size changed by uniformtofill strectch in ViewModel (wpf) 如何将pictureBox1中的图像替换为pictureBox1矩形区域上绘制的裁剪图像? - How can i replace the image in pictureBox1 with a crop image of a drawn on the pictureBox1 rectangle area? 如何在应用程序顶部绘制正方形,获取正方形的坐标/大小,并检查正方形下方的图像是否已更改? - How do I draw squares on top of applications, get coordinates/size of the squares, and check to see if the image beneath the squares has changed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM