Highlighted

Get Aspect Ratio from Cropped Dimensions [LUA, Plugin, SDK]

New Here ,
Jun 12, 2020

Copy link to clipboard

Copied

I think I have been looking at this too long - as it should be fairly simple!

In my plug-in, I need to be able to categorise images by their aspect ratio (e.g., 1x1, 3x2, 4x3, 16x9, etc).  Can anyone tell me the formula I can use (or an LUA function) that would return a "photo-friendly" aspect ratio from the photo's cropped dimensions?

Many thanks

Phil

Most Valuable Participant
Correct answer by johnrellis | Most Valuable Participant

WobertC's method won't quite work. Consider a 5472 x 3648 photo (a 3 x 2 ratio). When I crop that to 2338 wide, maintaining the original ratio, LR truncates the desired 1558 2/3 pixel height to 1558 (it should have rounded to 1559 rather than truncating, but LR gets much of the arithmetic of cropping a little wrong).  Neither 2338 x 1558 nor 2338 x 1559 simplify to 3 x 2. 

 

So instead, the code should search through the list of common photo ratios, looking for one that matches the cropped dimensions, possibly off by one pixel:

 

local ratios = {{1, 1}, {3,2}, {4, 3}, {5, 4}, {16, 9}}

local function aspectRatio (w, h)
    if w < h then w, h = h, w end
    for _, ratio in ipairs (ratios) do
        local rw, rh = ratio [1], ratio [2]
        local delta = math.abs (rw / rh * h - w)
        if delta <= 1 then return rw, rh end
        end
    return nil, nil
    end

 

But note that there are many cameras that produce images claiming a 3 x 2 aspect ratio but that are in fact slightly different:

 

Nikon D90, 4288 x 2848 ~ 1.5056

Nikon D3200, 6016 x 4000 = 1.504

Nikon D750, 6016 x 4016 ~ 1.498

Canon EOS Rebel T1i, 5477 x 3651 ~ 1.50014

 

(These are just some of the cameras from my catalog that I looked at.) All but the last differ by more than one pixel in width from the 3 x 2 aspect ratio. So if you want to label these as "3 x 2", you'll need to use a "fuzzier" test:

       local delta = math.abs (rw / rh - w / h)
       if delta <= 0.006 then return rw, rh end

I don't have an exhaustive list of camera sensors, so I don't know if the maximum delta of 0.06 is the best value.

 

Of course, this "fuzzy" matching will include crops that also don't quite match the common ratios exactly (or off by one pixel). 

 

[Use the blue reply button under the first post to ensure replies sort properly.]

Topics

SDK

Views

299

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Get Aspect Ratio from Cropped Dimensions [LUA, Plugin, SDK]

New Here ,
Jun 12, 2020

Copy link to clipboard

Copied

I think I have been looking at this too long - as it should be fairly simple!

In my plug-in, I need to be able to categorise images by their aspect ratio (e.g., 1x1, 3x2, 4x3, 16x9, etc).  Can anyone tell me the formula I can use (or an LUA function) that would return a "photo-friendly" aspect ratio from the photo's cropped dimensions?

Many thanks

Phil

Most Valuable Participant
Correct answer by johnrellis | Most Valuable Participant

WobertC's method won't quite work. Consider a 5472 x 3648 photo (a 3 x 2 ratio). When I crop that to 2338 wide, maintaining the original ratio, LR truncates the desired 1558 2/3 pixel height to 1558 (it should have rounded to 1559 rather than truncating, but LR gets much of the arithmetic of cropping a little wrong).  Neither 2338 x 1558 nor 2338 x 1559 simplify to 3 x 2. 

 

So instead, the code should search through the list of common photo ratios, looking for one that matches the cropped dimensions, possibly off by one pixel:

 

local ratios = {{1, 1}, {3,2}, {4, 3}, {5, 4}, {16, 9}}

local function aspectRatio (w, h)
    if w < h then w, h = h, w end
    for _, ratio in ipairs (ratios) do
        local rw, rh = ratio [1], ratio [2]
        local delta = math.abs (rw / rh * h - w)
        if delta <= 1 then return rw, rh end
        end
    return nil, nil
    end

 

But note that there are many cameras that produce images claiming a 3 x 2 aspect ratio but that are in fact slightly different:

 

Nikon D90, 4288 x 2848 ~ 1.5056

Nikon D3200, 6016 x 4000 = 1.504

Nikon D750, 6016 x 4016 ~ 1.498

Canon EOS Rebel T1i, 5477 x 3651 ~ 1.50014

 

(These are just some of the cameras from my catalog that I looked at.) All but the last differ by more than one pixel in width from the 3 x 2 aspect ratio. So if you want to label these as "3 x 2", you'll need to use a "fuzzier" test:

       local delta = math.abs (rw / rh - w / h)
       if delta <= 0.006 then return rw, rh end

I don't have an exhaustive list of camera sensors, so I don't know if the maximum delta of 0.06 is the best value.

 

Of course, this "fuzzy" matching will include crops that also don't quite match the common ratios exactly (or off by one pixel). 

 

[Use the blue reply button under the first post to ensure replies sort properly.]

Topics

SDK

Views

300

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Adobe Community Professional ,
Jun 12, 2020

Copy link to clipboard

Copied

Being curious, following thread for possible answers. Working from pixel dimensions to an aspect ratio is mathematics.

You are looking for math that finds the 'Ratio in lowest common denominator'

https://www.calculatorsoup.com/calculators/math/ratio-simplifier.php

[LUA, Plugin, SDK]- Way above my "pay grade"- sorry!

Regards. My System: Lr-Classic 9.4, Lightroom 3.4, Photoshop 2020 (21.2.1), Nikon DSLR, Windows-10.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jun 13, 2020

Copy link to clipboard

Copied

Thanks WobertC, but I am glad John came with an easier option - maths was never a strong subject for me 🙂

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Jun 12, 2020

Copy link to clipboard

Copied

WobertC's method won't quite work. Consider a 5472 x 3648 photo (a 3 x 2 ratio). When I crop that to 2338 wide, maintaining the original ratio, LR truncates the desired 1558 2/3 pixel height to 1558 (it should have rounded to 1559 rather than truncating, but LR gets much of the arithmetic of cropping a little wrong).  Neither 2338 x 1558 nor 2338 x 1559 simplify to 3 x 2. 

 

So instead, the code should search through the list of common photo ratios, looking for one that matches the cropped dimensions, possibly off by one pixel:

 

local ratios = {{1, 1}, {3,2}, {4, 3}, {5, 4}, {16, 9}}

local function aspectRatio (w, h)
    if w < h then w, h = h, w end
    for _, ratio in ipairs (ratios) do
        local rw, rh = ratio [1], ratio [2]
        local delta = math.abs (rw / rh * h - w)
        if delta <= 1 then return rw, rh end
        end
    return nil, nil
    end

 

But note that there are many cameras that produce images claiming a 3 x 2 aspect ratio but that are in fact slightly different:

 

Nikon D90, 4288 x 2848 ~ 1.5056

Nikon D3200, 6016 x 4000 = 1.504

Nikon D750, 6016 x 4016 ~ 1.498

Canon EOS Rebel T1i, 5477 x 3651 ~ 1.50014

 

(These are just some of the cameras from my catalog that I looked at.) All but the last differ by more than one pixel in width from the 3 x 2 aspect ratio. So if you want to label these as "3 x 2", you'll need to use a "fuzzier" test:

       local delta = math.abs (rw / rh - w / h)
       if delta <= 0.006 then return rw, rh end

I don't have an exhaustive list of camera sensors, so I don't know if the maximum delta of 0.06 is the best value.

 

Of course, this "fuzzy" matching will include crops that also don't quite match the common ratios exactly (or off by one pixel). 

 

[Use the blue reply button under the first post to ensure replies sort properly.]

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Adobe Community Professional ,
Jun 12, 2020

Copy link to clipboard

Copied

"fuzzy" is the word.

I knew you, John, would have an answer. 🙂

Regards. My System: Lr-Classic 9.4, Lightroom 3.4, Photoshop 2020 (21.2.1), Nikon DSLR, Windows-10.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jun 13, 2020

Copy link to clipboard

Copied

Thanks John - I think that gives me a very good start.   I will test it against my images and see if it can correctly pick-up the aspect ratios.

Phil

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
New Here ,
Jun 16, 2020

Copy link to clipboard

Copied

Works 🙂     Thanks for the function John

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Jun 16, 2020

Copy link to clipboard

Copied

Good. Which version of "match" are you using?  

 

[Use the blue reply button under the first post to ensure replies sort properly.]

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
james89a LATEST
New Here ,
Jun 16, 2020

Copy link to clipboard

Copied

Hi John

 

This version....

 

local ratios = {{1, 1}, {3,2}, {4, 3}, {5, 4}, {16, 9}}

local function aspectRatio (w, h)
    if w < h then w, h = h, w end
    for _, ratio in ipairs (ratios) do
        local rw, rh = ratio [1], ratio [2]
        local delta = math.abs (rw / rh * h - w)
        if delta <= 1 then return rw, rh end
        end
    return nil, nil
    end

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...