Image size calculation by keeping aspect ratio with different screen resolutions
Asked Answered
D

2

6

I am trying to resize an image by keeping the aspect ratio. It should be just large enough to fill the screen with no blank space and if necessary some of the image should be off-screen.

The image below shows how the yellow image should be sized based on the black screen size.

enter image description here

Heres the Code that I am actually using, is there any better way to do this?

if(bwidth > bheight) {
    if(bwidth > swidth && bheight > sheight) {
        new_height = sheight;
        new_width = (int) ((double) (bwidth/100)*(sheight/((double) (bheight)/100)));

    } else if(bwidth > swidth && bheight < sheight) {
        new_height = sheight;
        new_width = (int) ((double) (bwidth/100)*(sheight/((double) (bheight)/100)));

    } else if(bwidth < swidth && bheight < sheight) {
        new_height = sheight;
        new_width = (int) ((double) (bwidth/100)*(sheight/((double) (bheight)/100)));

    } else if(bwidth < swidth && bheight > sheight) {
        new_height = sheight;
        new_width = (int) ((double) (bwidth/100)*(sheight/((double) (bheight)/100)));

    } else if(bwidth >= swidth && bheight >= sheight) {
        new_width = swidth;
        new_height = (int) ((double) (bheight/100)*(swidth/((double) (bwidth)/100)));
    }

} else if(bwidth < bheight) {
    if(bwidth > swidth && bheight > sheight) {
        new_width = swidth;
        new_height = (int) ((double) (bheight/100)*(swidth/((double) (bwidth)/100)));

    } else if(bwidth < swidth && bheight > sheight) {        
        new_width = swidth;
        new_height = (int) ((double) (bheight/100)*(swidth/((double) (bwidth)/100)));

    } else if(bwidth < swidth && bheight < sheight) {
        new_width = swidth;
        new_height = (int) ((double) (bheight/100)*(swidth/((double) (bwidth)/100)));

    } else if(bwidth < swidth && bheight < sheight) {
        new_width = swidth;
        new_height = (int) ((double) (bheight/100)*(swidth/((double) (bwidth)/100)));

    } else if(bwidth >= swidth && bheight >= sheight) {
        new_width = swidth;
        new_height = (int) ((double) (bheight/100)*(swidth/((double) (bwidth)/100)));

    }
}
  • swidth = screen width
  • sheight = screen height
  • bwidth = image width
  • bheight = image height
Dolt answered 7/1, 2013 at 14:17 Comment(4)
do you want to cut invisible area or to change ratioKatharinekatharsis
i don't know if cutting is necessary, since it will be not visible, it should just fit the screen, alwaysDolt
you have quite a lot of redundant code there - how about re-factoring it to its essentials so that it's easier to read?Heidy
Very well asked question.Dosi
D
-4

Well thank you @Erick Robertson Changed a litte bit, but now it works!

Here is the changed code:

if (bwidth / swidth <  bheight / sheight) {
    new_width = swidth;
    new_height = (int) Math.floor((double) bheight 
                                  * (double) swidth / (double) bwidth);
} else {
    new_height = sheight;
    new_width = (int) Math.floor((double) bwidth 
                                 * (double) sheight / (double) bheight);
}
Dolt answered 7/1, 2013 at 14:43 Comment(1)
Why would you post an answer to your own question and then accept that instead of the answer whose information enabled you to solve your problem? This seems very irregular.Swanger
P
10

Compare ratios.

If the width to height ratio of the image is more than the width to height ratio of the screen, then you know you'll be using the screen width and calculating the height. Otherwise you'll be using the screen height and calculating the width. Just make sure none of the heights are zero!

Note that the code here will resize the image so that it will always fill the screen. This effectively crops off any additional part of the image. To make the image as large as possible while being entirely visible, change the < to a > in the first line.

if (bwidth / bheight < swidth / sheight) {
    new_width = swidth;
    new_height = (int) Math.floor((double) bheight
                                  * (double) swidth / (double) bwidth);
} else {
    new_height = sheight;
    new_width = (int) Math.floor((double) bwidth
                                 * (double) sheight / (double) bheight);
}

I also made a couple more improvements:

  • Simplified the equations. Dividing a numerator and denominator both by 100 doesn't do anything.
  • Simplified the typecasting. I don't know the type of each variable, but they all need to be doubles.
  • Used Math.floor instead of just a typecast to int to make sure it doesn't round up.
Paraboloid answered 7/1, 2013 at 14:27 Comment(4)
wait.. i am testing your code, i changed a little bit, works now on widescreen pictures :)Dolt
I think I had my understanding backwards. The code I wrote was so that you could see the entire image on your screen. It looks like you want to fill the screen and guarantee scrolling in only one direction?Paraboloid
just filling, without scrolling.. the code i changes to works for me.. thank you for your helpDolt
Okay, I went ahead and updated the answer to reflect my better understanding of your requirements. Sorry, I had it backwards.Paraboloid
D
-4

Well thank you @Erick Robertson Changed a litte bit, but now it works!

Here is the changed code:

if (bwidth / swidth <  bheight / sheight) {
    new_width = swidth;
    new_height = (int) Math.floor((double) bheight 
                                  * (double) swidth / (double) bwidth);
} else {
    new_height = sheight;
    new_width = (int) Math.floor((double) bwidth 
                                 * (double) sheight / (double) bheight);
}
Dolt answered 7/1, 2013 at 14:43 Comment(1)
Why would you post an answer to your own question and then accept that instead of the answer whose information enabled you to solve your problem? This seems very irregular.Swanger

© 2022 - 2024 — McMap. All rights reserved.