Thread: Calculating new aspect ratio problem

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    106

    Calculating new aspect ratio problem

    Hi Guys,

    I'm writing a program that must display images of any size to a
    screen of dimensions 320x568.
    I'm handling fixing the aspect ratio myself.
    I have handled the cases where both image dimensions are smaller
    than screen dimensions (just print it in the middle of the screen).
    And also handled where only one image dimension is larger than
    one screen dimension (resize the image making the larger
    image dimension match the screen dimension).

    Having some trouble deciding what to do if both image dimensions
    are larger than both screen dimensions:

    Code:
    if (oldx > 320 && oldy > 568) { // image is taller and wider than the screen
        if (oldx-320 < oldy-568) {
        newx = oldx / oldy * 568; // get new width
        newy = 568;
        posx = centerx - (newx/2); // get new x position
        posy = centery - (newy/2);    
        } else {
        newy = oldy / oldx * 320; // get new height
        newx = 320;
        posy = centery - (newy/2); // get new y position
        posx = centerx - (newx/2);    
        }
        }
    centerx and century are just coordinates for the centre of the screen,
    and might as well be 160 and 284...
    They are only variables because I sometimes move the image around.

    Now one example actual problem is, if the input image dimensions are
    640x958, the output dimensions are 379x568 (adjusted to the wrong dimension so 379 is wider than the screen),
    if the input dimensions are 534x660, the output is 320x395... Correct!!

    I think the solution lies in the second if/then line.
    Any help appreciated!!


    EDIT,,, whoops.. posx and posy are the screen coords to draw the image.
    if the image is 320x568, posx and posy should both be zero because the
    image dimensions match the screen size exactly.
    Last edited by xArt; 01-28-2013 at 07:28 PM.

  2. #2
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Personally, I would resize based on whichever dimension has the bigger overage in dimension, then the other.

    Meaning if you have dimensions of 100x50 and you have an image of size 200x100, the 200 is 100 over the max width while the 100 is only 50 over the max height so I would resize (keeping the same aspect ration of 2:1) so that the width is 100 and the height in that case would then be 50 as well (this is a perfect scenario of course where the ratio comes out perfect).

  3. #3
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Actually what I said is already what you are doing and is wrong to boot....it seems like you just need to instead record both aspect ratios by dividing the target height by the height of the image and same for the width, then multiply both dimensions by the smaller of the two quotients.

    A simple google search of 'resize aspect ratio algorithm'

  4. #4
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Yes, it is more compacted than it seems.
    You can turn the greater than sign around, and different images will come out wrong.
    I'll take a look on Google... how I got the aspect ratio formula in the first place..

  5. #5
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Yeah this Stack Overflow discussion seems to have some pretty good solutions:
    php - Algorithm to resize image and maintain aspect ratio to fit iPhone - Stack Overflow

  6. #6
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Yes, iPhone 5, good guess!

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The main change you need to make for this sort of thing is to do the multiplication before the division.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Is that faster? The aspect ratio formula is correct,
    Just the logic I'm applying to use it.

  9. #9
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    I did solve it myself, although in a way that I'm sure would be embarrassing compared
    to something more thought out:

    Code:
        int checkwidthagain;
        int checkheightagain;
        checkwidthagain = 0;
        checkheightagain = 0;
            
    if (oldx > 320 && oldy > 568) { // image is taller and wider than the screen
        if (oldx-320 < oldy-568) {
    newx = oldx / oldy * 568; // get new width
        newy = 568.0;
        checkwidthagain = 1;
    posx = centerx - (newx/2); // get new x position
        posy = centery - (newy/2);    
        } else {
    newy = oldy / oldx * 320; // get new height
        newx = 320.0;
        checkheightagain = 1;
    posy = centery - (newy/2); // get new y position
        posx = centerx - (newx/2);    
        }
        }
        
        if (checkwidthagain == 1 && newx > 320.0) {
    newy = oldy / oldx * 320; // get new height
        newx = 320.0;
    posy = centery - (newy/2);
    posx = centerx - (newx/2);
        } // checkwidthagain
            
        if (checkheightagain == 1 && newy > 568.0) {
    newx = oldx / oldy * 568; // get new width
        newy = 568.0;
    posx = centerx - (newx/2);
    posy = centery - (newy/2);
        } // checkheightagain
    
    Solves any situation where both image dimensions are larger than both screen dimensions.
    I'll cheat now, since this has to happen in real time adjusting size.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by xArt View Post
    Is that faster? The aspect ratio formula is correct,
    Just the logic I'm applying to use it.
    It can be faster, in that it allows you to use entirely integer math and not involve floating point at all. Like this:
    Code:
    newx = 568 * oldx / oldy;
    Otherwise if you try and use integer math, you get a significantly lower result than you want.

    Using floating point math leaves you with a likely result that the answer is off by 0.00001 or something, which then rounds down when you poke that value into an int.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Thanks, I will take that on board, however, screen coords are floats for iOS quartz2D
    The screen resolution is twice the coordinate dimensions (for current devices).
    ie. you draw a circle the old fashioned way, and the gfx chip takes care of anti-aliasing.
    or, you can draw a line from x0.5 y1.0 to x10.5 y11.0 if you like

    I only copy the values to ints to display the resolution to the user,
    but it's nice if they can be a little more accurate.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Aspect Oriented Programming
    By audinue in forum Tech Board
    Replies: 6
    Last Post: 05-26-2009, 04:42 AM
  2. 2:1 Aspect Ratio
    By Wraithan in forum Game Programming
    Replies: 6
    Last Post: 02-09-2006, 02:17 AM
  3. Memory Hit Ratio
    By MB1 in forum Tech Board
    Replies: 2
    Last Post: 12-03-2005, 02:46 PM
  4. Golden Ratio
    By mas in forum C++ Programming
    Replies: 1
    Last Post: 05-24-2004, 09:20 AM
  5. Who agrees with MS in this aspect?
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 12-21-2001, 01:05 PM