0

I'm working on an app feature where the user selects a portion of an image I have displayed by drawing a rectangle over it,

Rectangle Selection in Image Control

And then the cropped part of the image pops up in another Image control in the window. I have a Mouse Down, Mouse Move, and Mouse Up event to gather the starting coordinates, width, and height of this rectangle, and have successfully gotten the cropped selection to display, but the result is slightly off on the X-axis when you select something from the top of the image, and as you get closer to the bottom, the skew becomes more and more dramatic for both X and Y.

Cropped Bitmap Result from Top of Page

2nd Selection Near Bottom of Page

Cropped Bitmap Result of 2nd Selection

As it stands right now, I have an Image control (ImageViewer1) and a Canvas (Canvas1) layered on top of that where the blue Rectangle is drawn. The Canvas fits the size of the document displayed in the Image control (ImageViewer1.Source), so all coordinates plotted should match exactly.

First, I gathered the mouse's first coordinates in my MouseDown event:

var mouseDownPosition = Mouse.GetPosition(Canvas1); 
mouseDownPoint = new System.Windows.Point(mouseDownPosition.X, mouseDownPosition.Y);
//^^ I know this was unnecessary, but it's there now lol 

Kept drawing the rectangle in my MouseMove event (no issues there), Then collected the final coordinates of the mouse in my MouseUp event:

var mouseUpPosition = Mouse.GetPosition(Canvas1); 
mouseUpPoint = new System.Windows.Point(mouseUpPosition.X, mouseUpPosition.Y); 

int rectX = Convert.ToInt32((Math.Min(mouseDownPoint.X, mouseUpPoint.X))); 
int rectY = Convert.ToInt32((Math.Min(mouseDownPoint.Y, mouseUpPoint.Y))); 

int rectWidth = Convert.ToInt32((Math.Abs(mouseUpPoint.X - mouseDownPoint.X))); 
int rectHeight = Convert.ToInt32((Math.Abs(mouseUpPoint.Y - mouseDownPoint.Y))); 

int sourceToActualXRatio = Convert.ToInt32(imageWidth / ImageViewer1.Source.Width); 
int sourceToActualYRatio = Convert.ToInt32(imageHeight / ImageViewer1.Source.Height); 

rectX *= sourceToActualXRatio; 
rectY *= sourceToActualYRatio;
 
rectWidth *= sourceToActualXRatio; 
rectHeight *= sourceToActualYRatio; 

imageWidth and imageHeight contain the measurements of the actual full-size image, and I created ratios from them (sourceToActualXRatio, sourceToActualYRatio) to multiply my rectangle measurements by so that I could scale it up and get the right selection.

I think this is working because the dimensions seem correct in the CroppedBitmap, but the X and Y axis placement is just wildly unpredictable, so I think there's logic to how the rectX and rectY variables must be scaled that I'm missing.

Finally, I create the CroppedBitmap with those rectangle dimensions:

BitmapSource bms = (BitmapSource)ImageViewer1.Source; 
CroppedBitmap cropped_bitmap = new CroppedBitmap(bms, new Int32Rect(rectX, rectY, rectWidth, rectHeight)); 
ImageViewer2.Source = cropped_bitmap; 

Thanks to anyone willing to help!

7
  • Do you want to explain why you're "scaling" while "cropping"? That's what's moving your "x and y" and your "width and height". The issue becomes more severe as "Top" increases. I see no need for "scaling" at this stage of the operation. Commented Jun 14, 2024 at 21:06
  • @GerrySchmitz it's so bizarre, I thought for sure I wouldn't have to scale since the Image source and canvas match each other, but for some reason, when I remove the scaling, my selection is super zoomed-in to the top left corner, as if the cropped image is sampling the actual large image instead of the ImageViewer1.Source as I specified. any thoughts? Commented Jun 17, 2024 at 20:42
  • It's not always obvious which element your need to get the "mouse position" from (we can't see all your XAML). You might try a different element in your "Mouse.GetPosition(...)"; e.g. The "image". I you pick the "wrong" element, your coordinates will be different than expected. Commented Jun 18, 2024 at 20:43
  • I also noticed you don't "capture" the mouse. I capture it on "pointer down", BEFORE anything else; get my positions during the moves, etc; and release the mouse on "pointer up"; AFTER anything else I need to do. learn.microsoft.com/en-us/dotnet/api/… Commented Jun 19, 2024 at 18:55
  • Would it be useful to share all XAML? The only relevant elements that I thought to share were the Image control (ImageViewer1) and the Canvas (Canvas1) that is layered on top of it, which contains the rectangle you draw. I'll try other elements as well, and thank you for the mouse capturing tip also! You've given me some good food for thought. Commented Jun 19, 2024 at 21:16

1 Answer 1

-1

You should convert to integer only in the very last step of the calculation.

Example calculation for X

Variable Value
imageWidth 4200
ImageViewer1.Source.Width 887
mouseDownPoint.X 150
mouseUpPoint.X 500
Variable Current Should Be
sourceToActualXRatio 4 4.735062
rectX  600 710
rectWidth 1400 1657
double rectXf = Math.Min(mouseDownPoint.X, mouseUpPoint.X); 
double rectYf = Math.Min(mouseDownPoint.Y, mouseUpPoint.Y); 

double rectWidthf = Math.Abs(mouseUpPoint.X - mouseDownPoint.X); 
double rectHeightf = Math.Abs(mouseUpPoint.Y - mouseDownPoint.Y); 

double sourceToActualXRatio = imageWidth / ImageViewer1.Source.Width; 
double sourceToActualYRatio = imageHeight / ImageViewer1.Source.Height; 


rectXf *= sourceToActualXRatio; 
rectYf *= sourceToActualYRatio;
 
rectWidthf *= sourceToActualXRatio; 
rectHeightf *= sourceToActualYRatio;

int rectX = Convert.ToInt32(rectXf);
int rectY = Convert.ToInt32(rectYf);
int rectWidth = Convert.ToInt32(rectWidthf);
int rectHeight = Convert.ToInt32(rectHeightf);
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for these recommendations! I could see how it would really skew my results. I made the adjustments and am hoping for higher precision when I figure this out, but unfortunately the general issues persist.
But you did not include that general issue in this question, you did not include enough details to describe that issue. I have only answered that part you mentioned in your question, because I am very bad in reading brains ;o) You may ask another question which describes your general issue
Sorry, I think you misunderstood. You helped me a lot by letting me know about the integers! I was just saying that the X-axis skew at the top of the page and further offset near the bottom during the selection process (as I originally stated) was unfortunately still off for me. I mentioned that I thought it had something to do with how I was scaling. No shade to you at all - only gratitude.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.