Thursday, July 1, 2010

Computing aspect ratio

Well, duh, it's easy, right?  Yeah, just divide the width by the height and there you go.  But what if you want to compute, say, a "pretty" (i.e. human-readable) representation of it instead of just the floating point representation?  You'll need a bit more math for that.

I wrote a command line PHP script to do exactly this because I wanted a utility that I could feed the filename of an image and have it spit out the dimensions, aspect ratio, and type, completely on my server without having to open up the samba share on my desktop and do anything graphically.

Computing it in a more human-readable representation is pretty simple.  The required mathematical operation is the greatest common denominator.  Computing that isn't obvious at first, but it's pretty simple.  There's a recursive method that's short and sweet.  I actually got it off of a comment on the reference article for mathematical functions on PHP.net.

Here it is, spaced out for readability:
function gcd( $n, $m )
{if ( !$m )
  return $n;
 return gcd( $m, $n % $m );
}
Basically, what's happening is you're computing the GCD of the second number and their modulus (remainder after division) until the second number is zero, and once it is zero, you're returning that second number (which gets continually shifted into the first argument).

So, for instance, let's say we have a 1920x1200 image.  I won't step through the recursion, but the GCD of those two numbers is 240.  So then, we divide the length of each dimension by the GCD to get a human-readable aspect ratio.  It's that simple.

1920/240 = 8
1200/240 = 5

And there you go, it's 8:5.  If you're anal about checking the answer, divide 1920 by 1200, then divide 8 by 5.  You'll get 1.6 in both cases.

This is essentially just reducing a fraction programmatically, but applied to the dimensions of an image file.

I used PHP basically so I could cheat and have it do the dirty work of figuring out the image type and parsing it to get the dimensions for me.  getimagesize() is your friend.

Note that there is a library for PHP that does provide a GCD function, but it's horrible.  You have to convert your numbers to a different type first and then cope with how they're not actually numbers after that.  I just wanted a function that operated on integers and returned an integer, so I could shove all the numbers and strings into printf() to make it look nice.

No comments:

Post a Comment

I moderate comments because when Blogger originally implemented a spam filter it wouldn't work without comment moderation enabled. So if your comment doesn't show up right away, that would be why.