[英]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.