How can I convert the XY coordinates and height / width on a scaled image to an image with the original size?

Question related to us

I am trying to do the same thing as in a related question, but with C #. I show a scaled image and let the user select the area to crop. However, I can’t just take the x1y1, x2y2 coordinates from the scaled image selection and crop it from the original. I tried to do basic math, as in another question, but this is obviously not the right approach (it is definitely closer).

Edit

Original Image Size: w = 1024 h = 768

Scalable Image Sizes: w = 550 h = 412

I start with an image, say, 1024x768. I want it to fit as much as possible in a 550x550 box. I use the following method to get the size of the scaled image (while maintaining the aspect ratio). Then I make the base size for these new dimensions.

As for the selection area, it can be anything (from 0.0) to (100,100).

 private static Rectangle MaintainAspectRatio(Image imgPhoto, Rectangle thumbRect) { int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; int sourceX = 0; int sourceY = 0; int destX = 0; int destY = 0; float nPercent = 0; float nPercentW = 0; float nPercentH = 0; nPercentW = ((float)thumbRect.Width / (float)sourceWidth); nPercentH = ((float)thumbRect.Height / (float)sourceHeight); //if we have to pad the height pad both the top and the bottom //with the difference between the scaled height and the desired height if (nPercentH < nPercentW) { nPercent = nPercentH; destX = (int)((thumbRect.Width - (sourceWidth * nPercent)) / 2); } else { nPercent = nPercentW; destY = (int)((thumbRect.Height - (sourceHeight * nPercent)) / 2); } int destWidth = (int)(sourceWidth * nPercent); int destHeight = (int)(sourceHeight * nPercent); Rectangle retRect = new Rectangle(thumbRect.X, thumbRect.Y, destWidth, destHeight); return retRect; } 
+8
c # image-scaling
source share
2 answers

Without a bit more details, I assume that you are actually suffering from rounding errors ...
- When you scale (top, left) coordinate back to the original, you need to round off (top left).
- When you scale (bottom, right) coordinate back to the original, you need to round (right to right)

Take a simple example of a 12x12 grid as the original and a 4x4 grid as a scaled version.
- (1,1) :( 2,2) on the scaled version = (3,3) :( 8,8)
- 2x2 pixel = 25% of the scaled version area
- 6x6 pixels = 25% of the area of ​​the original version

If we simply multiply by the same scale factors, this would give (3.3): (6.6).


OriginalTop = INT (ScaledTop * YScalingFactor);
OriginalLeft = INT (ScaledLeft * XScalingFactor);

OriginalBottom = INT ((ScaledBottom + 1) * YScalingFactor) - 1;
OriginalRight = INT ((ScaledRight + 1) * XScalingFactor) - 1;


EDIT

The best way to explain what I'm trying to say is to draw a picutra. And I suck in ASCII Art. So here is another attempt with words.

The pixel is not a point. This is a small rectangle in its own right.

When you use a pixel to represent the upper left corner of a rectangle, you include the area from the upper left of the point's point.

When you use a pixel to represent the Lower Right Rectangle, you include the area completely at the point. The lower right point of the point.


Using the example (12x12) => (4x4), each scaled pixel represents a whole set of 3 Γ— 3 pixels in the original. Speaking of the top left, you select the top left pixel of the 3x3 pixel group in the original. And when you talk about the lower right, you select the lower right part of the 3x3 pixel group in the original.


EDIT : using integers.

 NewTop = (( OldTop ) * NewHeight / OldHeight); NewLeft = (( OldLeft ) * NewWidth / OldWidth ); NewBottom = ((OldBottom + 1) * NewHeight / OldHeight) - 1; NewRight = ((OldRight + 1) * NewWidth / OldWidth ) - 1; 


The only consideration is that you are not overflowing your data type after multiplication. But with the images you will not, unless it is a damn image.

+7
source share

You can get the percentage for scaled images and return them back to the coordinates for the unscaled image:

 pX1 = scaledX1/scaled_width pY1 = scaledY1/scaled_height unscaledX1 = ceiling(unscaled_width * pX1) unscaledY1 = ceiling(unscaled_height * pY1) 
0
source share

All Articles