Aleksey Lavrov
Aleksey Lavrov

Reputation: 41

Converting picture coordunates to canvas coordinates

I have an Image control with loaded picture (source is BitmapImage, stretch is Uniform) on my window. I want to place Border control over Image control accordingly frame coordinates in source image.

For example:

source image height: 1500 pixels

source image width: 1000 pixels

frame x: 700 pixels

frame y: 500 pixels

frame width: 100 pixels

frame height: 150 pixels

I've tried

var verticalRatio = this.ImageBitmap.ActualHeight / ((BitmapImage)this.ImageBitmap.Source).PixelHeight;
var horizontalRatio = this.ImageBitmap.ActualWidth / ((BitmapImage)this.ImageBitmap.Source).PixelWidth;

It seems it works for Border's size, but Border is shifted. I think it occurs because Image displays picture scaled and picture have some margin inside Image.

Something like this

What I should do to solve this problem?

Thanks

Upvotes: 1

Views: 119

Answers (1)

Aleksey Lavrov
Aleksey Lavrov

Reputation: 41

I've found answer. I calculate ratios and shifts for current Image control which is placed in one parent container with Canvas control. I placed this code in helper as static method:

public static void CalculateRatios(Panel panel, BitmapImage image, ref double horizontalShift, ref double verticalShift, ref double horizontalRatio, ref double verticalRatio)
    {
        panel.UpdateLayout();

        var ratioSource = image.PixelWidth / image.PixelHeight;
        var ratioImage = panel.ActualWidth / panel.ActualHeight;

        Size pictureInControlSize;

        if (ratioSource > ratioImage) // image control extended in height
        {
            pictureInControlSize = new Size(panel.ActualWidth, panel.ActualWidth / ratioSource);
        }
        else if (ratioSource < ratioImage) // image control extended in width
        {
            pictureInControlSize = new Size(panel.ActualHeight * ratioSource, panel.ActualHeight);
        }
        else // image control have the same proportions
        {
            pictureInControlSize = new Size(panel.ActualWidth, panel.ActualHeight);
        }

        horizontalShift = (panel.ActualWidth - pictureInControlSize.Width) / 2d;
        verticalShift = (panel.ActualHeight - pictureInControlSize.Height) / 2d;
        horizontalRatio = pictureInControlSize.Width / image.PixelWidth;
        verticalRatio = pictureInControlSize.Height / image.PixelHeight;
    }

First I calculate ratios:

ImageHelper.CalculateRatios(this.LayoutCanvas, (BitmapImage)this.ImageFingersBitmap.Source, ref _horizontalShift, ref _verticalShift, ref _horizontalRatio, ref _verticalRatio);

Then I use it to calculate the size and location of my border:

Width = box.Size.Width * _horizontalRatio,
Height = box.Size.Height * _verticalRatio,
Canvas.SetLeft(contentControl, _horizontalShift + box.TopLeft.X * _horizontalRatio);
Canvas.SetTop(contentControl, _verticalShift + box.TopLeft.Y * _verticalRatio);

Upvotes: 0

Related Questions