Tuesday, January 27, 2009

png to gif transformation - an excellent free solution via PHP GD2

Why we still need png to gif in our web pages

There a couple of valid plugins for different libraries able to manage "silently" png transparency in order to fix those browsers (cough: IE6) that are still used, for god knows which reason, but not able to understand properly the alpha channel. The problem is that these plugins cause overhead in our pages and for each png images, which is nearly a non-sense since these plugins fix old browsers whose performances have never been brilliant!
Especially for modern GUIs, where little icons are widely used, these plugins could make the application incredibly slow.
If we could choose old good GIF instead of png, 'till the end of those browsers, the problem will not exist and performances will be acceptable.

PNG 2 GIF, simple? ... not, really!

First of all a couple of search via Google brought me in "free but you have to pay anyway" applications through some open source, simple, but not that nice, program language solution, incompatible with modern interpreters or not able to produce a good quality result.
The problem is basically this one: alpha channel is something amazing, but it changes border colors if we are putting the png over a bright background rather than a dark one.
For this reason it is really difficult to obtain a valid GIF copy of the original PNG feel using common transformers, since the main difference is given by our cool theme that can be bright or dark.
Thanks to PHP and its distributed GD2 library, I have been able to create a good compromise between pixelated borders and our chose theme.

png2gif, the php/gd2 way

function png2gif($pngs, $background = array(255, 255, 255), $dest = 'gif'){
// by WebReflection
foreach($pngs as $png){
$size = getimagesize($png);
$img = imagecreatefrompng($png);
$image = imagecreatetruecolor($width = $size[0], $height = $size[1]);
imagefill($image, 0, 0, $bgcolor = imagecolorallocate($image, $background[0], $background[1], $background[2]));
imagecopyresampled($image, $img, 0, 0, 0, 0, $width, $height, $width, $height);
imagecolortransparent($image, $bgcolor);
imagegif($image, str_ireplace('.png', '.gif', $dest.DIRECTORY_SEPARATOR.basename($png)), 100);

// example

That's it, you copy and paste an entire directory into, for example, an icons folder, and you call the function passing the list of files contained in that directory.
Parameters are the file list itself, the background color, and finally the destination folder to put transformed png into gif, by default the dir "gif".
The main difference between this function and every other method I found, is that borders are gracefully adapted to your main theme, by default a bright one with white background.
In this way you can choose how borders should be readapted instead of black borders for alpha problems, or cutted one. Even circle icons result are, in my opinion, brilliant!
The array should contain R,G,B integer values, from 0 to 255, where array(0,0,0) is black and array(255,255,255) is white, the default background theme.

You can try this function to convert most common icons theme, and please tell me if the result was not good enough ;-)

P.S. for PHP maniacas, the imagecopyresampled gd2 function has been the only one able to merge properly the png into chose background color ... I don't want to tell you how long did it take to find this kind of solution (passing via pixel by pixel color allocation ... omg!)

No comments: