Как получить прямоугольник, нарисованный на украшателе, чтобы масштабировать его с элементом Image, с которым он связан, когда размер окна изменяется? - PullRequest
2 голосов
/ 19 сентября 2019

Я использую прямоугольник, нарисованный на украшении, чтобы отметить интересующую область на изображении.Проблема в том, что, если я изменю размер окна, прямоугольник не изменит размер.

Я новичок в WPF, поэтому я провел кучу исследований, пытаясь найти, что я могу, с помощью нескольких различных поисковых терминов.,На самом деле я только что выучил украшения таким образом, и я дошел до этого далеко, но я наткнулся на стену о том, как закончить этот последний кусок.Я знаю, что моя проблема основана на размере прямоугольника, но я не знаю, что захватывать / искать, чтобы настроить его, так как wpf изменяет размер фактического объекта изображения при изменении размера окна, поэтому нет никакого коэффициента масштабирования, на который можно смотреть.

Вот 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>

Класс Adorner:

    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)
        {
        }
    }

Желаемый результат заключается в том, что прямоугольник масштабируется вместе с объектом изображения, чтобы он всегда покрывал одну и ту же область изображения.Проблема в том, что я не знаю, как получить масштабный коэффициент для увеличения и уменьшения масштаба при изменении размера окна.

Обновление: после обдумывания предложения Френчи я понял, что ответ прост: «Нормализовать ваши координаты»

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

Подход, который я использовал бы, состоит в том, чтобы сделать изображение и прямоугольник одинаковыми.Затем эта одна вещь растягивается, масштабируется или как угодно.

Один из способов сделать это - использовать 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. Вы можете рассчитать размеры, привязать или растянуть в соответствии с вашими требованиями.

0 голосов
/ 19 сентября 2019

вы просто адаптируете свой метод рендеринга следующим образом:

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 дает вам размер изображения.

...