Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

math/algorithm Fit image to screen retain aspect ratio

I need help with math / algorithm to take an image of known size and fit to one of two screen dimensions:

720 x 480 or 1280 x 1024.

The image dimensions are coming from an XML file, however those dimensions are the web dimensions, I also get a selection of images from the XML that may be of higher and lower resolution than the web dimensions.

What I want is to use the aspect ration of the web dimensions to display the higher resolution image, if available, on an HD (1280x720) screen, or, if the user is on an SD screen (720x480) display the image on that screen.

Other things that would be useful for this, but lower priority, would be, if I know the resolution of the image is smaller in both dimensions than an SD screen (in this case, all I know is the web dimension, and the horizontal dimension of the image file), to display it as actual size on that screen.

Hope that is clear enough.

Thanks!

like image 228
alphablender Avatar asked Jul 03 '11 21:07

alphablender


People also ask

How do I lock the aspect ratio of an image?

Insert Pictures, Select the picture, Right Click, and click Picture… Click Size and do not check Lock aspect ratio, then set the scale and click OK. Right Click, and click Picture…, then check Lock aspect ratio. After this, when you adjust the size by pulling the corners of the picture, the ratio is fixed.


2 Answers

Generic as can be:

Image data: (wi, hi) and define ri = wi / hi
Screen resolution: (ws, hs) and define rs = ws / hs

Scaled image dimensions:

rs > ri ? (wi * hs/hi, hs) : (ws, hi * ws/wi) 

So for example:

         20 |------------------|     10 |---------|  --------------------     ---   --- |         |        |      | 7   | |         |        |      |     | 10 |----------        |     ---    | |                  |            | --------------------           ---  ws = 20 hs = 10 wi = 10 hi = 7  20/10 > 10/7 ==> (wi * hs/hi, hs) = (10 * 10/7, 10) = (100/7, 10) ~ (14.3, 10) 

Which as you can see clearly scales to the screen size, because the height is that of the screen but clearly keeps aspect ratio since 14.3/10 ~ 10/7

UPDATE

Center the image as follows:

call (wnew, hnew) the new dimensions.

top = (hs - hnew)/2 left = (ws - wnew)/2 
like image 175
davin Avatar answered Sep 29 '22 09:09

davin


I understand the accepted answer and it works, but I've always found the following method to be simpler and succinct for "best fit":

// prep let maxWidth = 190,     maxHeight = 150; let imgWidth = img.width,     imgHeight = img.height;  // calc let widthRatio = maxWidth / imgWidth,     heightRatio = maxHeight / imgHeight; let bestRatio = Math.min(widthRatio, heightRatio);  // output let newWidth = imgWidth * bestRatio,     newHeight = imgHeight * bestRatio; 

... which of course can be distilled down to:

const maxWidth = 190, maxHeight = 150; const bestRatio = Math.min(maxWidth / img.width, maxHeight / img.height); img.width *= bestRatio; img.height *= bestRatio; 
like image 37
pstanton Avatar answered Sep 29 '22 08:09

pstanton