Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is resized PNG image so much bigger than original image?

I am quite confused why PNG images that are resized using GD library are much bigger in size than the original.

This is the code I am using to resize the image:

// create image from posted file
$src = imagecreatefrompng($file['tmp_name']);
// get original size of uploaded image
list($width,$height) = getimagesize($file['tmp_name']);
if($width>$maxImgWidth) {
    // resize the image to maxImgWidth, maintain the original aspect ratio
    $newwidth = $maxImgWidth;
    $newheight=($height/$width)*$newwidth;
    $newImage=imagecreatetruecolor($newwidth,$newheight);

    // fill transparent with white
    /*$white=imagecolorallocate($newImage, 255, 255, 255); 
    imagefill($newImage, 0, 0, $white);*/

    // the following is to keep PNG's alpha channels
    // turn off transparency blending temporarily
    imagealphablending($newImage, false);
    // Fill the image with transparent color
    $color = imagecolorallocatealpha($newImage,255,255,255,127);
    imagefill($newImage, 0, 0, $color); 
    // restore transparency blending
    imagesavealpha($newImage, true);

    // do the image resizing by copying from the original into $newImage image
    imagecopyresampled($newImage,$src,0,0,0,0,$newwidth,$newheight,$width,$height);

    // write image to buffer and save in variable
    ob_start(); // Stdout --> buffer
    imagepng($newImage,NULL,5); // last parameter is compression 0-none 9-best (slow), see also http://www.php.net/manual/en/function.imagepng.php
    $newImageToSave = ob_get_contents(); // store stdout in $newImageToSave
    ob_end_clean(); // clear buffer
    // remove images from php buffer
    imagedestroy($src);
    imagedestroy($newImage);
    $resizedFlag = true;
}

Then I save $newImageToSave as blob in mysql database.

I tried to prevent alpha channel and just set white background, no significant change in file size. I tried setting the "compression" parameters (0 to 9), but still bigger then the original.

Example
I took this image (1058px*1296px) and resized it to 900px * 1102px. These are the results:

Original File: 328 KB
PNG (0): 3,79 MB
PNG (5): 564 KB
PNG (9): 503 KB

Any tip how to get the resized image smaller in file size is appreciated.

--

PS: I thought it could be bit depth, but as you can see, the example image above has 32 bits, whereas the resized image is 24 bits.

like image 254
Avatar Avatar asked Nov 06 '12 18:11

Avatar


1 Answers

You don't most of the functions you are calling to reduce the image , imagefill , imagealphablending etc can result to higher file size.

To Maintain the transparent use imagecreate instead of imagecreatetruecolor and just do a simple resize

$file['tmp_name'] = "wiki.png";
$maxImgWidth = 900;
// create image from posted file
$src = imagecreatefrompng($file['tmp_name']);
// get original size of uploaded image
list($width, $height) = getimagesize($file['tmp_name']);
if ($width > $maxImgWidth) {
    $newwidth = $maxImgWidth;
    $newheight = ($height / $width) * $newwidth;
    $newImage = imagecreate($newwidth, $newheight);
    imagecopyresampled($newImage, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
    imagepng($newImage, "wiki2.png", 5); 
    imagedestroy($src);
    imagedestroy($newImage);
    $resizedFlag = true;
}

Final Size : 164KB

like image 70
Baba Avatar answered Nov 19 '22 11:11

Baba