Ako môžem previesť z myš súradnice pixel súradnice TransformedBitmap?

0

Otázka

Moja otázka je podobná Ako sa dostať na správne pozície kurzora z myš súradnice?, s pridanou námietka, že obraz je potenciálne TransformedBitmaptam , kde sa prevracia a rotácie by sa mohli uplatniť, a ešte vrátiť pixel súradnice pôvodného obrazu.

Môj Window"s dizajnom vyzerá takto:

    <DockPanel>
        <Label DockPanel.Dock="Bottom" Name="TheLabel" />
        <Image DockPanel.Dock="Top" Name="TheImage" Stretch="Uniform" RenderOptions.BitmapScalingMode="NearestNeighbor" MouseMove="TheImage_MouseMove" />
    </DockPanel>

a codebehind vyzerá takto:

        public MainWindow()
        {
            InitializeComponent();

            const int WIDTH = 4;
            const int HEIGHT = 3;
            byte[] pixels = new byte[WIDTH * HEIGHT * 3];
            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 = bs;
        }

        private void TheImage_MouseMove(object sender, MouseEventArgs e)
        {
            Point p = e.GetPosition(TheImage);
            if (TheImage.Source is TransformedBitmap tb)
                TheLabel.Content = tb.Transform.Inverse.Transform(new Point(p.X * tb.PixelWidth / TheImage.ActualWidth, p.Y * tb.PixelHeight / TheImage.ActualHeight)).ToString();
            else if (TheImage.Source is BitmapSource bs)
                TheLabel.Content = new Point(p.X * bs.PixelWidth / TheImage.ActualWidth, p.Y * bs.PixelHeight / TheImage.ActualHeight).ToString();
        }

Keď sa vznáša v pravom dolnom rohu (ktoré som modrej farby pre jednoduché sledovanie) non-transformovaný obraz, ste správne vidieť súradnice (~4, ~3), ktoré sú rozmery obrazu.

enter image description here

Avšak, keď použijete transformovať, napríklad zmena TheImage.Source = bs; na TheImage.Source = new TransformedBitmap(bs, new RotateTransform(90.0));, vznášajúce sa nad modrá namiesto dáva (~4, ~0).

enter image description here

Myslím, že jeden môže pozrieť na skutočné matice hodnôt premeniť, a zistiť, ako nastaviť bod v rôznych prípadoch, ale zdá sa, ako by tam mali byť jednoduchšie riešenie pomocou inverznej transformácie.

.net bitmapsource c# image
2021-11-23 06:19:28
1

Najlepšiu odpoveď

1

Keď sa obrazový prvok poskytuje a TransformedBitmap, centrum bod Transformácia účinne ignorovať a bitová mapa sa posunie do vhodnej koordinovať rozsahu.

Keďže tento posun nie je aplikovaný na transfomation Bodu, budete musieť kompenzovať to, napr. ako tento:

var p = e.GetPosition(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)
    {
        var w = tb.Source.PixelWidth;
        var h = tb.Source.PixelHeight;

        p = tb.Transform.Inverse.Transform(p);

        p = new Point((p.X + w) % w, (p.Y + h) % h);
    }

    TheLabel.Content = $"x: {(int)p.X}, y: {(int)p.Y}";
}

Vyššie uvedený kód sa však nebudú fungovať správne, keď Transformácie centra je nastavená na hodnotu než (0,0).

Aby to fungovalo pre Transformuje s neobmedzenou stredu, máte jasné posunu hodnôt v transformovať matice:

var p = e.GetPosition(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)
    {
        var w = tb.Source.PixelWidth;
        var h = tb.Source.PixelHeight;
        var t = tb.Transform.Value;
        t.Invert();
        t.OffsetX = 0d;
        t.OffsetY = 0d;

        p = t.Transform(p);

        p = new Point((p.X + w) % w, (p.Y + h) % h);
    }

    TheLabel.Content = $"x: {(int)p.X}, y: {(int)p.Y}";
}
2021-11-23 10:54:45

Vďaka! Ak jeden vloží Image v Grid ktorá má zázemie a pohybuje MouseMove akcie k Grid, pixel súradnice sú už nie je presný, keď sa nachádzate mimo hranice obraz, pretože to dáva len odpovede od 0..šírka a 0..výšky. Akýkoľvek nápad, ako to opraviť?
Craig W

Existuje viacero spôsobov. Najviac jednoduchý, pripojte obsluhu udalosti do inej vnorenej rodičovský prvok, ktorý má rovnaké rozmery ako Obraz. Inak existuje viacero spôsobov, ako TransformToDescendant alebo podobné.
Clemens

Nie ste si istí, budem nasledovať. Môžem preložiť bod z nadradenej sústavy na obraz, žiadny problém. Ale napríklad, keď používateľ prejde vpravo otočený obraz, chcel by som, y-súradnicu byť negatívne, aby odrážali, ktoré sú vyššie uvedené hranice obrázok v pôvodnej orientácie. By som sa mal upraviť moju otázku, alebo začať novú?
Craig W

Lepšie napísať novú.
Clemens

V iných jazykoch

Táto stránka je v iných jazykoch

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