views:

39

answers:

3

I have an image (i) that's been scaled from its original size (rectLarge) to fit a smaller rectangle (rectSmall). Given a point p in rectSmall, how can I translate this to a point in rectLarge.

To make this concrete, suppose I have a 20x20 image that's been scaled to a 10x10 rect. The point (1, 1) in the smaller rect should be scaled up to a point in the larger rect (i.e. (2,2)).

I'm trying to achieve this with:

result.x = point.x * (destRect.size.width / srcRect.size.width );
result.y = point.y * (destRect.size.height / srcRect.size.height);

However, the points generated by this code are not correct - they do not map to the appropriate point in the original image. What am I doing wrong?

A: 

What is the "appropriate point"? If the size of srcRect is larger than destRect then your code is correct. Also, don't forget that result.x and result.y will be a floating point number and to use them in the image you need to round it or do bilinear interpolation, etc. Before, I can give a more detailed answer, what are you going to do with result?

Jacob
To elaborate a little, I have an image which is slightly larger than the available screen. The image is scaled down slightly for a "Preview" mode where the user clicks a point to indicate a region.I need to translate that point from the preview image's rectangle to the original image in order to process the region.srcRect is larger than destRect.
Bill
Then, `point` is from the smaller rectangle, which means `result` should be in the larger rectangle, which implies you're scaling up, so it should be `srcRect.width/destRect.width` ?
Jacob
A: 

I guess the problem is that your rectangle is positioned not at (0, 0) and, therefore, you can't scale every point inside it the same way as you scale it's dimensions.

You will have to determine the offset from some anchor point in your rectangle (for example, top left point), then your resulting point would be anchor_point.x + offset.x * (horizontal_scale_ratio) and the same for y (with vertical_scale_ratio).

Ratios there are new_width / old_width and new_height / old_height.

Kotti
(point.x, point.y) is relative to the top-left of the smaller rectangle.
Bill
Then I think your problem is either in another place or smth like that. The chunk of code you've posted seems good and I don't suspect any problems in it.
Kotti
+1  A: 

What language are you using?

If this is C, and rect.size.height and the like are ints, then you have a major rounding problem. Say you're scaling point 10, 10 from a size 20x20 back up to a size 30x30. Your calculations will look like:

result.x = 10 * (30 / 20);

This simplifies to:

result.x = 10 * (1);

The simplest way to fix this is to get rid of the parentheses:

result.x = point.x * destRect.size.width / srcRect.size.width;
result.y = point.y * destRect.size.height / srcRect.size.height;

Now your calculation, 10 * 30 / 20, simplifies to 300 / 20 and then to 15, which is what you want.

Note, you still have a slight rounding problem, but unless you can get subpixel locations, this is about as close as you're gonna get.

clahey
Objective-C, so C arithmetic rules apply. These values are all floats.
Bill