This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Java in General and the fly likes Resize an image while maintaing its aspect ratio.. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Resize an image while maintaing its aspect ratio.." Watch "Resize an image while maintaing its aspect ratio.." New topic
Author

Resize an image while maintaing its aspect ratio..

Monu Tripathi
Rancher

Joined: Oct 12, 2008
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?

[List of FAQs] | [Android FAQ] | [Samuh Varta]
Monu Tripathi
Rancher

Joined: Oct 12, 2008
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

Joined: Oct 27, 2005
Posts: 19651
    
  18

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.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Carey Brown
Ranch Hand

Joined: Nov 19, 2001
Posts: 173



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

Joined: Oct 12, 2008
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

Joined: Oct 12, 2008
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
Marshal

Joined: Mar 22, 2005
Posts: 41088
    
  43
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.


Ping & DNS - my free Android networking tools app
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19651
    
  18

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

Joined: Oct 12, 2008
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

Joined: Oct 27, 2005
Posts: 19651
    
  18

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

Joined: Oct 12, 2008
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!
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Resize an image while maintaing its aspect ratio..
 
Similar Threads
Aspect ratio-preserving image scaling, drawing and infinite loops
Adjusting the size of an image (jpg)?
JFrame resize problem
Resizing JPG using Graphics2D
disappearing square