Cum pot converti de la mouse-ul coordonatele pixel de coordonate de un TransformedBitmap încorporat într-o mai mare container părinte?

0

Problema

Similar Cum pot converti de la mouse-ul coordonatele pixel de coordonate de un TransformedBitmap? dar cu a adăugat rid mea Image este, de fapt, încorporate într-o mai mare părinte Grid, care are un fundal, și aș dori pixel de coordonate să fie, de asemenea, corecte, atunci când sunt situându-se în regiunile de dincolo de imagine.

Aici este meu XAML:

    <DockPanel>
        <Label DockPanel.Dock="Bottom" Name="TheLabel" />
        <Grid DockPanel.Dock="Top" Name="TheGrid" Background="Gray" MouseMove="TheGrid_MouseMove">
            <Image Name="TheImage" Stretch="Uniform" RenderOptions.BitmapScalingMode="NearestNeighbor" />
        </Grid>
    </DockPanel>

Și aici este codul:

        public MainWindow()
        {
            InitializeComponent();

            const int WIDTH = 4;
            const int HEIGHT = 3;
            byte[] pixels = new byte[WIDTH * HEIGHT * 3];
            // top-left corner red, bottom-right corner blue for orientation
            pixels[0] = Colors.Red.B;
            pixels[1] = Colors.Red.G;
            pixels[2] = Colors.Red.R;
            pixels[(WIDTH * (HEIGHT - 1) + (WIDTH - 1)) * 3 + 0] = Colors.Blue.B;
            pixels[(WIDTH * (HEIGHT - 1) + (WIDTH - 1)) * 3 + 1] = Colors.Blue.G;
            pixels[(WIDTH * (HEIGHT - 1) + (WIDTH - 1)) * 3 + 2] = Colors.Blue.R;
            BitmapSource bs = BitmapSource.Create(WIDTH, HEIGHT, 96.0, 96.0, PixelFormats.Bgr24, null, pixels, WIDTH * 3);
            TheImage.Source = new TransformedBitmap(bs, new RotateTransform(90.0));
        }

        private void TheGrid_MouseMove(object sender, MouseEventArgs e)
        {
            Point p = TheGrid.TranslatePoint(e.GetPosition(TheGrid), TheImage);
            if (TheImage.Source is BitmapSource bs)
            {
                p = new Point(p.X * bs.PixelWidth / TheImage.ActualWidth, p.Y * bs.PixelHeight / TheImage.ActualHeight);
                if (TheImage.Source is TransformedBitmap tb)
                {
                    Matrix inverse = tb.Transform.Value;
                    inverse.Invert();
                    inverse.OffsetX = 0.0;
                    inverse.OffsetY = 0.0;
                    p = inverse.Transform(p);
                    int w = tb.Source.PixelWidth;
                    int h = tb.Source.PixelHeight;
                    p = new Point((p.X + w) % w, (p.Y + h) % h);
                }
                TheLabel.Content = p.ToString();
            }
        }

Pentru cea mai mare parte acest lucru funcționează bine, dar dacă treceți în gri din stânga imaginea rotită (aproximativ unde X este în imaginea de mai jos), veți obține o coordonata y (0.5), care o face să arate ca tine sunt în imagine, atunci când în realitate sunt în afara, și y-coordonata ar trebui să fie mai mare decât înălțimea imaginii pentru a reflecta acest lucru.

enter image description here

Acest lucru este important pentru că încerc să-permite utilizatorului să selecteze un ROI, și trebuie să știu atunci când selecția este dincolo de imaginea limite, deși eu încă mai vreau să-l permite.

.net bitmapsource c# image
2021-11-23 17:48:44
1

Cel mai bun răspuns

1

Puteti efectua o transformare pe un "test point" în interiorul imaginii limite (de exemplu, centru) și modulo funcționare pe transformată punct de încercare. Apoi, utilizați compensarea între transformat punct de încercare și ajustate (de modulo) punct de testare pentru a ajusta punctul real.

var p = e.GetPosition(TheImage);

p = new Point(
    p.X * bs.PixelWidth / TheImage.ActualWidth,
    p.Y * bs.PixelHeight / TheImage.ActualHeight);

if (TheImage.Source is TransformedBitmap tb)
{
    var inverse = tb.Transform.Value;
    inverse.Invert();
    inverse.OffsetX = 0.0;
    inverse.OffsetY = 0.0;

    var w = tb.Source.PixelWidth;
    var h = tb.Source.PixelHeight;

    var v = new Vector(bs.PixelWidth / 2, bs.PixelHeight / 2); // test point
    var v1 = inverse.Transform(v); // transformed test point
    var v2 = new Vector((v1.X + w) % w, (v1.Y + h) % h); // adjusted

    p = inverse.Transform(p) - v1 + v2; // add adjusting offset
}

TheLabel.Content = $"x: {p.X:F2}, y: {p.Y:F2}";
2021-11-23 22:03:56

Un punct de încercare din centrul imaginii; idee frumoasă. Multumesc!!!
Craig W

În alte limbi

Această pagină este în alte limbi

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................