Fare koordinatlarından daha büyük bir üst kapsayıcıya gömülü bir transformedbitmap'in piksel koordinatlarına nasıl dönüştürebilirim?

0

Soru

Fare koordinatlarından dönüştürülen Bitmap'in piksel koordinatlarına nasıl dönüştürebilirim? ama eklenen kırışıklık ile benim Image aslında daha büyük bir ebeveyne gömülüdür Grid bir arka plana sahip olan ve görüntünün sınırlarının ötesindeki bölgelerde gezinirken piksel koordinatlarının da doğru olmasını istiyorum.

İşte benim xaml'm:

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

Ve işte kod:

        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();
            }
        }

Çoğunlukla bu iyi çalışır, ancak döndürülmüş görüntünün solundaki gri renkte gezinirseniz (kabaca X'in aşağıdaki ekran görüntüsünde olduğu yerde), gerçekte dışarıdayken görüntüde olduğunuz gibi görünmesini sağlayan bir y koordinatı (0.5) elde edersiniz ve y koordinatı bunu yansıtmak için görüntü yüksekliğinden daha yüksek olmalıdır.

enter image description here

Bu önemlidir, çünkü kullanıcının bir yatırım getirisi seçmesine izin vermeye çalışıyorum ve seçimin görüntü sınırlarının ötesinde ne zaman olduğunu bilmem gerekiyor, ancak yine de buna izin vermek istiyorum.

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

En iyi cevabı

1

Dönüşümü görüntü sınırları içindeki bir "test noktasında" (ör.Merkez) ve dönüştürülen test noktasında modulo işlemi gerçekleştirebilirsiniz. Ardından, gerçek noktayı ayarlamak için dönüştürülmüş test noktası ile ayarlanmış (modulo ile) test noktası arasındaki ofseti kullanın.

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

Görüntünün ortasından bir test noktası; güzel fikir. Teşekkürler!
Craig W

Diğer dillerde

Bu sayfa diğer dillerde

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