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ž

Developer technologies Windows Presentation Foundation
Developer technologies C#
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Viorel 122.6K 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 );
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.