I have a small PHP script which converts image files to thumbnails. The uploader I have has a 100MB max, which I'd like to keep.
The problem is, when opening the file, GD decompresses it, causing it to be huge and make PHP run out of memory (Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 64000 bytes)
). I don't want to increase my memory any further than this allowed size.
I don't care about the image, I can just make it show a default thumbnail, that's fine. But I do need a way to catch the error imagecreatefromstring(file_get_contents($file))
spawns when the image is too big.
Since the error spawned is fatal, it cannot be try-catched, and since it loads it in one command, I can't keep looking after it to make sure it's not approaching the limit. I need a way to calculate how big the image will be before trying to process it.
Is there a way to do this? filesize
wouldn't work as it gives me the compressed size...
My code is as follows:
$image = imagecreatefromstring(file_get_contents($newfilename));
$ifilename = 'f/' . $string . '/thumbnail/thumbnail.jpg';
$thumb_width = 200;
$thumb_height = 200;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// Image is wider than thumbnail.
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// Image is taller than thumbnail.
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $ifilename, 80);
Tried looking at the original image size before re-sizing? Maybe multiplying it by a set % based of average format compression?
$averageJPGFileRatio = 0.55;
$orgFileSize = filesize ($newfilename) * 0.55;
and looking at that before doing any work?
Secondary idea
Calculate it like this: width * height * 3 = filesize
The 3 is for the red, green, and blue values if you're working with images with an alpha channel use 4 instead of 3. This should give you a VERY close estimation of the bitmap size. Does not take into account header info, but that should be negligible at a few bytes.