WPF Image mouse pointer coordinates

Primož Žufič 1 Reputation point
2021-03-30T12:45:54.343+00:00

Hello,

I'm trying to make a custom window which displays an image and allows the user to draw/drag a rectangle on it.

I'm using a Canvas which contains Image and Rectangle. Rectangle is drawn fine according to the pointer location, but I'm having issues with coordinates transformation to the image itself. It works fine on the external screen but it produces location and size errors on my laptop screen.

Main part of the XAML:

<Grid >
            <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
            <Canvas Name="canvas" MouseMove="ctlCanvas_MouseMove" MouseDown="ctlCanvas_MouseDown" MouseUp="ctlCanvas_MouseUp">
                <Image x:Name="ctlImage" Source="{Binding Image, UpdateSourceTrigger=PropertyChanged}" Width="{Binding Path=ActualWidth, ElementName=canvas}" Height="{Binding Path=ActualHeight, ElementName=canvas}" Stretch="Uniform"/>
                <Rectangle Stroke="Red" Fill="Transparent" IsHitTestVisible="False" Visibility="{Binding CanvasSelectionVisibility}" Width="{Binding CanvasSelectionWidth}" Height="{Binding CanvasSelectionHeight}" Canvas.Left="{Binding CanvasSelectionPositionLeft}" Canvas.Top="{Binding CanvasSelectionPositionTop}"/>
            </Canvas>
        </Grid >

Code for transforming coordinates from Canvas to the image itself:

        public static System.Drawing.Point GetImageCoordinates(MouseButtonEventArgs e, System.Windows.Controls.Image imageControl)
        {
            System.Windows.Point imageControlPosition = e.GetPosition(imageControl);
            return new System.Drawing.Point((int)Math.Floor(imageControlPosition.X * imageControl.Source.Width / imageControl.ActualWidth), (int)Math.Floor(imageControlPosition.Y * imageControl.Source.Height / imageControl.ActualHeight));
        }

Maybe I'm missing something but I wasn't able to figure it out.

Thank you for your help in advance.

Have a nice day ;),

Primož

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,185 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
7,007 questions
No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Viorel 82,911 Reputation points
    2021-03-30T20:10:13.593+00:00

    Check if this works:

    <Image 
        x:Name="ctlImage" 
        HorizontalAlignment="Left"
        VerticalAlignment="Top" 
        Width="{Binding Path=ActualWidth, ElementName=canvas}" 
        Height="{Binding Path=ActualHeight, ElementName=canvas}" 
        Stretch="Uniform" />
    

    In your function:

    return e.GetPosition( ctlImage );