Search code examples
mathscale

Math - Getting Maximum Proportionate Image Scale


I need an algorithm which will determine the maximum scale increase that is possible for an image.

The rules (size limitation of a BitmapData object for the Flash Player, but this is not a Flash question):

  1. both the width and length of the image must be less than 8,191 pixels
  2. the maximum number of pixels in the image can not exceed 16,777,215

therefore, as mentioned in the documentation:

if a BitmapData object is 8,191 pixels wide, it can only be 2,048 pixels high.

In my code, I first determine if any of these rules are broken and throw and error if they are. this lets me know that any image that is loaded and does not throw an error has scalability.

The image I'm using is 2514 width x 1029 height. This image will not throw an error since both width and height are less than 8,191 and it's pixel count, or width multiplied by height, is less than 16,777,215.

I identify as being right-brained and don't have much confidence in my math skills, but the following is what I've come up with to determine the maximum allowed scale for the image.

private static const MAX_BITMAP_MEASUREMENT:uint = 8191;
private static const MAX_BITMAP_PIXELS:uint = 16777215;

var imageWidth:uint = 2514;
var imageHeight:uint = 1029;

var roughScaleUp:Number = 1.0 / Math.max(imageWidth, imageHeight) * MAX_BITMAP_MEASUREMENT;
var scaleBack:Number = Math.max(Math.min(imageWidth, imageHeight) * roughScaleUp - MAX_BITMAP_PIXELS / MAX_BITMAP_MEASUREMENT, 0);
var maxScale:Number = 1.0 / (Math.max(imageWidth, imageHeight) + scaleBack) * MAX_BITMAP_MEASUREMENT;

This code outputs the maximum scale for my image as 2.145144435977516, but I tested it and there is still a lot of pixel space remaining, so it should be able to be scaled up more and I'm pretty sure my code is terribly wrong.

Any math wizards on here care to help out a lowly art school graduate? I'm fully ready to accept that there is probably a much more simplistic solution to this problem and I'm prepared for the lashings.


Solution

  • You have to multiply both the width and the height by a constant, and the scaled result of the multiplication should be less than 16777215.

    So

    a^2 * w * h == 16,777,215
    

    Which yields, for your values of w and h

    a = 2.5466520486244177 [= Sqrt(16,777,215 / (w*h)) ]
    

    So , for your values for the new w and h, you get:

    NewW = a * w = 6402.283250241786
    NewH = a * h = 2620.5049580345258  
    

    ... just round them down :)