PHP - resize image to a specific (k) size?
January 12, 2006 8:53 AM   Subscribe

Formula to resize an image (in PHP) so that the resulting file is roughly a certain size in bytes?

The task: If a file uploaded through a web form is >50k, scale it down so it's about 50k.

My PHP code for the actual scaling is working fine; what I'm trying to figure out is the best way to calculate the target height and width. (Leaving JPEG quality out of the equation for the time being.) This tends to produce files that are too large:

$pct = ($max_k * 1024) / filesize($file);
list($width_orig, $height_orig) = getimagesize($file);
$height = $height_orig * $pct;
$width = $width_orig * $pct;

I think I need to somehow either adjust the percentage based on the proportion between the two dimensions, or multiply the area by the percentage to get a desired area and then do something with that, but what? Square roots?

Or is it going to come out inaccurately whatever I do because there's so much variation among individual images?

Any suggestions appreciated.
posted by staggernation to Computers & Internet (8 answers total)
Or is it going to come out inaccurately whatever I do because there's so much variation among individual images?

There's your problem right there. JPG images can compress really, really well, or really really poorly... Your best bet, though it's somewhat system intensive, is a bit of "trial and error"... perhaps have 2 or 3 preset sizes to size down to, and automatically choose the one that is of optimal filesize using some formula.

Also, I know that many times programmers hate using external tools, but might I suggest ImageMagick? It will allow you to save at one fixed size, but varying levels of quality (or maybe php lets you do this natively? I dunno) so that you can choose the best image...
posted by twiggy at 8:55 AM on January 12, 2006

There is so much more info in a picture contributing to it's size other than it's literal dimensions. I can't imagine this would be possible.
posted by glenwood at 9:15 AM on January 12, 2006

Best answer: I would guess that there should be some correlation between percentage reduction and file size — for a specific given image. Not in general, like you are hoping for.

But you can still use this fact. You can calculate that ratio by doing a test resize, and then plug that in to get a percentage reduction that gives the appropriate filesize.
posted by smackfu at 9:50 AM on January 12, 2006

You can do this with a binary search. In pseudocode:

factor = 0.5
target_size = 50k
tolerance = 3k
new_image = resize_by(orig_image, factor)
diff = size(new_image) - target_size
if(diff > 0)
factor = factor / 1.5
factor = factor * 1.5
while(abs(diff) > tolerance)

Of course, you might want to limit the number of iterations to make sure that it converges without sucking down too much CPU usage.
posted by Rhomboid at 10:15 AM on January 12, 2006

er, scratch that... that will loop forever. You need something a little more sophisticated than just dividing/multiplying 'factor' by some consant. Store the previous version of 'factor' and make the new one halfway in between the current value and the last value.
posted by Rhomboid at 10:19 AM on January 12, 2006

Response by poster: smackfu: so simple, I never would have thought of it. But it got me a lot closer to 50k in most cases than any of the other weird geometry-based crap I tried. Thanks!
posted by staggernation at 7:48 PM on January 12, 2006

Using PHP to "resize" an image like that actually changes the file size? I would have thought it just changed the display size. The original file would still have to load, right?
posted by bricoleur at 5:29 AM on January 13, 2006

Response by poster: No, I'm using PHP's image functions to resample the image and save a new image file that's a smaller size, replacing the original.
posted by staggernation at 9:17 AM on January 13, 2006

« Older How do I get this dog urine smell out of our couch...   |   Where should I ski/stay in Quebec? Newer »
This thread is closed to new comments.