views:

247

answers:

2

Hi

I have image upload form, user attaches aimage file, and selects image size to resize the uploaded image file(200kb, 500kb, 1mb, 5mb, Original). Then my script needs to resize image file size based on user's optional size, but im not sure how to implement this feature,

For example, user uploads image with one 1mb size, and if user selects 200KB to resize, then my script should save it with 200kb size.

Does anyone know or have an experience on similar task ?

Thanks for you reply in advance.

+4  A: 

With the GD library, use imagecopyresampled().

<?php
// The file
$filename = 'test.jpg';
$percent = 0.5;

// Content type
header('Content-type: image/jpeg');

// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;

// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

// Output
imagejpeg($image_p, null, 100);
?>

Edit: If you want to resize the image file to a specified size, that's a little harder. All the major image formats use compression and compression rates vary by the nature of what's being compressed. Compress clear blue sky and you'll get a better compression ratio than you will sea of people.

The best you can do is try a particular size is try a particular size and see what the file size is, adjusting if necessary.

Resize ratio = desired file size / actual file size
Resize multipler = square root (resize ratio)
New height = resize multiplier * actual height
New width = resize multiplier * actual width

This basically factors in an approximation of the expected compression ratio. I would expect that you would have some tolerance (like +/- 5%) and you can tweak the numbers as necessary.

There is no direct way to resize to a particular file size. Lastly I'll add that resizing to a particular file size is rather unusual. Resizing to a particular height and/or width (maintaining aspect ratio) is far more common and expected (by users).

Update: as correctly pointed out, this gets the file size wrong. The ratio needs to be the square root of the file size ratios as you're applying it twice (once to height, once to width).

cletus
You'll end up with files half the size you want, since the fractional component "resize ratio" gets squared. If you have a 1MB image and you want an (approximately) 512KB file, you want to resize it so that newheight = sqrt(2) * height (likewise for width)
dcrosta
Thank you for your useful comments
shuxer
@dcrosta: quite right. Fixed to mltiply by sqrt(ratio).
cletus
+2  A: 

Using the GD Library provided in PHP:

// $img is the image resource created by opening the original file
// $w and $h is the final width and height respectively.
$width = imagesx($img);$height = imagesy($img);
$ratio = $width/$height;

if($ratio > 1){
// width is greater than height
$nh = $h;
$nw = floor($width * ($nh/$height));
}else{
$nw = $w;
$nh = floor($height * ($nw/$width));
}

//centralize image
$nx = floor(($nw- $w) / 2.0);
$ny = floor(($nh-$h) / 2.0);

$tmp2 = imagecreatetruecolor($nw,$nh);
imagecopyresized($tmp2, $img,0,0,0,0,$nw,$nh,$width,$height);

$tmp = imagecreatetruecolor($w,$h);
imagecopyresized($tmp, $tmp2,0,0,$nx,$ny,$w,$h,$w,$h);

imagedestroy($tmp2);imagedestroy($img);

imagejpeg($tmp, $final_file);

This piece of code will take the original image, resize to the specified dimensions. It will first try to ratio aspect resize the image, then crop off + centralize the image, making it fall nicely into the dimensions specified.

thephpdeveloper
i meant to resize image file size, not image size itself, for example, user uploads image with one 1mb size, and if user selects 200KB to resize, then my script should save it with 200kb size.
shuxer
like the other answer, if there is no definite answer of how much file size it will be after saving.
thephpdeveloper