Gublooo
Gublooo

Reputation: 2618

php compressing images showing varying results

I was using the firebug page speed utility and one of the suggestions given was to compress the images - So I wrote the following code to compress the image

$filename="http://localhost.com/snapshots/picture.png";
$img = imagecreatefrompng($filename);
$this->_response->setHeader('Content-Type', 'image/png');
imagepng($img,null,9);
imagedestroy($img);

Now the actual image size is 154K So I experimented by giving different quality levels and here is what I found

imagepng($img,null,0); --> Size = 225K
imagepng($img,null,1); --> Size = 85.9K
imagepng($img,null,2); --> Size = 83.7K
imagepng($img,null,3); --> Size = 80.9K
imagepng($img,null,4); --> Size = 74.6K
imagepng($img,null,5); --> Size = 73.8K
imagepng($img,null,6); --> Size = 73K
imagepng($img,null,7); --> Size = 72.4K
imagepng($img,null,8); --> Size = 71K
imagepng($img,null,9); --> Size = 70.6K

Do these results look accurate - I'm not sure why with quality 0 - the image size is larger than the actual size.

Secondly is this the best way to go about in PHP to compress images before rendering them in the browser to improve performance.

Based on the suggestions, that its better to compress the image once at the time of saving - I digged up the code that is called by the flash program to generate the snap shot -

$video = $this->_getParam('video'); 
$imgContent = base64_decode($this->_getParam('snapshot'));
file_put_contents("snapshots/" . $video . ".png", $imgContent);

EDITED Based on Alvaro's suggestion, I have made the following modification to the code which generates a much small jpg file

$video = $this->_getParam('video'); 
$imgContent = base64_decode($this->_getParam('snapshot'));
file_put_contents("snapshots/" . $video . ".png", $imgContent);

$filename="snapshots/".$video.".png";
$img = imagecreatefrompng($filename);
imagejpeg($img,'test.jpg',75);

So now this is a 3 step process

  1. create the initial image using file_put_contents
  2. Use imagecreatefrompng and imagejpeg to compress the file and generate a smaller image
  3. Delete the orig image

Is this the best optimal way to go about it.

Upvotes: 5

Views: 4346

Answers (3)

Álvaro González
Álvaro González

Reputation: 146660

Since PNG uses lossless data compression, the only way to achieve a decent compression in a PNG image (edge cases apart) is to save it as palette (rather than true colour) and reduce the number of colours. You appear to be processing some sort of screenshots. You may obtain smaller file sizes is you use a lossy compression, i.e., save as JPEG. In either cases, you reduce both file size and picture quality. You could also try the GIF format, which tends to be smaller for small graphs.

Last but not least, you should compress images once (typically when they get uploaded), not every time they're served. I suppose your code is just a quick test but I mention just in case.

Answer to updated question:

I'm not familiar with PHP image functions but you should probably use a combination of imagecreatefrompng() and imagejpeg(). Also, consider whether you need to keep the original PNG for future reference or you can discard it.

Upvotes: 4

Shikiryu
Shikiryu

Reputation: 10219

1- The result seems accurate since 0 means no compression

quality

Compression level: from 0 (no compression) to 9.

It's normal for the 0ed file to be larger than the original (that can be slightly compressed to begin with). You need to understand file compression and PHP GD image constructor.

2- IMHO, the wisest choice would be to compress your png file before uploading them on your server (of course, it states only if you have the choice : static, few files).

Help for that :

If it means to be dynamic, the php is the choice.

Upvotes: 0

mck89
mck89

Reputation: 19271

You have not understood the last parameter, that's not quality that's the compression level so increasing it will decrease the image size. Anyway i've used that method before to compress png images and it works well so i think you should continue to use it.

Upvotes: 3

Related Questions