• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Resize an image while maintaing its aspect ratio..

 
Rancher
Posts: 1369
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.






 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I use something like this when I want to "fit" an image into some fixed size destination.
 
Monu Tripathi
Rancher
Posts: 1369
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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(..).
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:....Just remember to change that last assignment to newWidth to newHeight instead


ah! a copy paste error! Sure, will. Many thanks!
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic