Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!

# Resize an image while maintaing its aspect ratio..

Monu Tripathi
Rancher
Posts: 1369
1
I need to resize an image while maintaining its aspect ratio. I have to resize it to fit screen dimensions which could be either : 320x480 or 480x320.
The algo that i wrote is:

where {newWidth, new Height} are new dimensions or destination dimensions..

Output after computation is:

Image size: 327 x 496
newWidth x newHeight: 320 x 455
scaledWidth x scaledHeight: 320 x 485

Does any one have a better algorithm to achieve this or is the algorithm sufficiently correct?

Monu Tripathi
Rancher
Posts: 1369
1
I did not express myself very well up there; here is a rephrasing of my problem...

I am trying to write a helper to an Image resizing function, this function is supposed to calculate the dimensions that the image should be resized to. The calculated dimensions will honor the image's aspect ratio. The Parameters passed to this function will include:

1. Original Dimensions or the image(direct dimensions/the image itself will be passed)
2. The new dimensions(newWidth, newWidth): These are expected bounds for the resized image. In other words, the final image can be no larger than (newWidth x newHeight).
3. All of these parameters are of integer type.

My current algorithm tries to do the following :
1. Determine Min(newWidth, newHeight).
2. If newWidth < newHeight the final image will have width = newWidth else it will have height = newHeight.
3. depending on the two above, measure the other component such that:
(origWidth/origHeight = newWidth/newHeight)

What is monu's problem here?

1. Has any one written any algorithm similar to this and can share?
2. Is there a better way to calculating the new size?

Thanks.

Rob Spoor
Sheriff
Posts: 20531
54
Your original code is not working, is it? The scaled height exceeds the desired height.

What I did some time ago to solve this is this:
- calculate the factor to scale the width by (newWidth / originalWidth)
- calculate the factor to scale the height by (newHeight / originalHeight)
- take the minimum of these
- scale both the original width and original height by that one factor

For an image of 327x496 and a desired size of 320x455, it will give you a size of 300x455. That fits completely in your desired size.

Carey Brown
Ranch Hand
Posts: 1479
17

I use something like this when I want to "fit" an image into some fixed size destination.

Monu Tripathi
Rancher
Posts: 1369
1
Your original code is not working, is it? The scaled height exceeds the desired height.

Exactly! I wanted to resize the image to a point where it can take up "most" of the {newHeight x newWidth} rectangle while maintaining its aspect ratio. I see your algorithm does that very well. I wrote a version of my own that does the same thing as yours albeit with more lines of code:

I think, I will use your algorithm in my program since it is more succint.

Thank you guys!
Note: I noticed that this is similar to resizing an object by dragging the hooks/handle given in the corners of cropping/resizing tools.

Monu Tripathi
Rancher
Posts: 1369
1
Monu Tripathi wrote:I think, I will use your algorithm in my program since it is more succint.

And perhaps easier to read and understand..But should I really do that now?
I will be running this code on a mobile platform (under tight constraints for memory and response times). A normal code flow for my program would do: one floating point division and one comparison. However, the one you suggested will do two floating point divisions and and a context switch to call Math.min(..).

Ulf Dittmer
Rancher
Posts: 42967
73
I'm fairly certain that an extra FP operation and an extra method call would not be noticeable by a human observer, so I wouldn't worry about the time they take to execute.

Rob Spoor
Sheriff
Posts: 20531
54
And if you really want to get rid of the method call to Math.min, replace its call by its body:
But again, as Ulf said, I doubt the very few nanoseconds this code will take will be noticeable.

And to prove it, I've just tried out Carey Brown's code:
The longest that code took on my PC was about 200,000 nanoseconds == 200 microseconds == 0.200 milliseconds. If I take out the dimensions but use ints instead, I don't even get above 0.100 milliseconds. Surely that's not that bad, is it?

Monu Tripathi
Rancher
Posts: 1369
1
Hmmm..interesting. I tested the independent runs of following two functions on Android G1 phone:

The run time range for first function() was: 1000,000 - 700,000 nano seconds and
that for function2() was: 800,000 - 180,000 ns.

I agree that the difference is not large enough to be perceptible. So, I think I am good with using any of the two versions, since both of them are functionally same. (naturally, I am a bit biased towards mine though )

Thanks for all your help and time!

Rob Spoor
Sheriff
Posts: 20531
54
Well, it is quite a bit faster on my machine too; just 3 microseconds as the highest. That's a factor 60 difference in your favour. Just remember to change that last assignment to newWidth to newHeight instead

Monu Tripathi
Rancher
Posts: 1369
1
Rob Prime wrote:....Just remember to change that last assignment to newWidth to newHeight instead

ah! a copy paste error! Sure, will. Many thanks!