Preserving GIF tansparencies when rebuilding thumbnails

streetjammer

New Member
On upload of images, the code creates several different thumbnails. In some cases, the thumbnail may be larger than the original image, in which case a padding is applied. In the case of JPEGs, the padding is white, and all is well. In the case of GIFs and PNGs, the padding should be transparent. And it is. Or not. Which is weird.If I was getting an entirely black or transparent padding, I'd have some idea where the problem is, but I'm getting paddings which are transparent in places and black in others, which makes no sense.Sample PNG and GIF images at http://filedump.xn--es-zka.info/broken_thumbs/ (on a shocking pink background colour so you can see the difference between white and transparent).
IVeag.png
Any bright ideas?\[code\]class Image { public static function exec($path) { // This function receives the path to an image. // Logic here skipped: For each thumbnail, check whether Crop is set. If it is, call self::crop(). Otherwise, call self::resize(). return true; } public static function resize($file, $class, $width='-', $height='-', $fit=0) { $a = getimagesize($file); switch ($a[2]) { case 1: $tag = 'gif'; break; case 2: $tag = 'jpeg'; break; case 3: $tag = 'png'; break; default: return; } $w = $a[0]; $h = $a[1]; if ($width == 0) { $fw = 0; $fh = $h / $height; } elseif ($height == 0) { $fw = $w / $width; $fh = 0; } else { $fw = $w / $width; $fh = $h / $height; } if (($fw == 1) and ($fh == 1)) { $file2 = dirname($file) . '/' . $class . basename($file); copy($file, $file2); return true; } elseif (($fw >= 1) and ($fh >= 1)) { if ($fw > $fh) { $w = $width; $h = floor($h / $fw); } else { $h = $height; $w = floor($w / $fh); } } elseif ($fh == 0) { if ($fw > 1) { $fit = 0; $w = $width; $h = floor($h / $fw); } else { if ($fit) { $height = $h; } } } elseif ($fw == 0) { if ($fh > 1) { $fit = 0; $w = floor($w / $fh); $h = $height; } else { if ($fit) { $width = $w; } } } elseif (($fw < 1) and ($fh < 1)) { // } elseif ($fw > $fh) { if ($fw >= 1) { $w = $width; $h = floor($h / $fw); } } elseif ($fh > $fw) { if ($fh >= 1) { $w = floor($w / $fh); $h = $height; } } if ($fit) { $x = ($width - $w) / 2; $y = ($height - $h) / 2; $cw = $width; $ch = $height; } else { $x = 0; $y = 0; $cw = $w; $ch = $h; } $file2 = dirname($file) . '/' . $class . basename($file); $f1 = 'imagecreatefrom' . $tag; $src = http://stackoverflow.com/questions/3815676/$f1($file); $new = imagecreatetruecolor($cw, $ch); return self::create($new, $src, $file2, $x, $y, $w, $h, $a); } public static function crop($file, $class, $width='-', $height='-', $fit=0) { if (!$class) return trigger_error('ExecImage: Original image can not be overwritten.'); $small = 0; $a = getimagesize($file); switch ($a[2]) { case 1: $tag = 'gif'; break; case 2: $tag = 'jpeg'; break; case 3: $tag = 'png'; break; default: return; } $w = $a[0]; $h = $a[1]; if ($height == 0) { //resize by width -- height will follow $fh = 0; $fw = $w / $width; } elseif ($width == 0) { //resize by height -- width will follow $fw = 0; $fh = $h / $height; } else { $fw = $w / $width; $fh = $h / $height; } if (($fw <= 1) and ($fh <= 1)) { $small = 1; //don't resize } else { $fit = 1; //chop by the smallest if ($fh < $fw) { //Crop By Height $h = $height; $w = floor($w / $fh); //$w = $width; //$h = floor($h /$fw); //$w = $width; } else { //Crop By Width $w = $width; $h = floor($h /$fw); //$h = $height; //$w = floor($w / $fh); } } $file2 = dirname($file) . '/' . $class . basename($file); $f1 = 'imagecreatefrom' . $tag; $src = http://stackoverflow.com/questions/3815676/$f1($file); if ($small) { if ($fit) { //image must be padded $x = ($width - $w) / 2; $y = ($height - $h) / 2; } else { //image goes as is -- shrinked $x = 0; $y = 0; } } else { //image must be centered -- this should be a square from js $x = ($width - $w) / 2; $y = ($height - $h) / 2; } if ($small) { if ($fit) { //create with the full size $new = imagecreatetruecolor($width, $height); } else { //nah, just with the original size $new = imagecreatetruecolor($w, $h); } } else { if ($fit) { $new = imagecreatetruecolor($width, $height); } else { $new = imagecreatetruecolor($w, $h); } } return self::create($new, $src, $file2, $x, $y, $w, $h, $a); } private static function create($new, $src, $file2, $x, $y, $w, $h, $a) { switch ($a[2]) { case 1: // GIF case 3: // PNG // http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/ // http://www.mummey.org/2008/11/transparent-gifs-with-php-and-gd/ imagealphablending($new, false); imagesavealpha($new, true); $back = imagecolorallocatealpha($new, 255, 255, 255, 127); imagefilledrectangle($new, 0, 0, $w, $h, $back); imagecolortransparent($new, $back); break; case 2: // JPEG $back = imagecolorallocate($new, 255, 255, 255); break; } imagefill($new, 0, 0, $back); imagecopyresampled($new, $src, $x, $y, 0, 0, $w, $h, $a[0], $a[1]); if (file_exists($file2)) unlink($file2); switch ($a[2]) { case 1: imagegif($new, $file2); break; case 2: imagejpeg($new, $file2, 100); break; case 3: imagepng($new, $file2, 0); break; } imagedestroy($src); imagedestroy($new); return true; }}\[/code\]Revision/Edit to add:Well, I've solved the main problem: padding added to PNG or GIF images is now transparent, instead of black. The smaller problem, that GIF transparency becomes black, is still with us, but I don't use GIF transparency much.\[code\]<?phpclass Image {public static function exec($path) { $file = Nearest::file('.config.php', dirname($path) . '/', BD . '/images/'); if (!file_exists($file)) exit('The ".config.php" file doesnt exist'); require $file; foreach ($config['operations'] as $k => $v) { if (!isset($v['class'])) $v['class'] = '.' . $k . '.'; if (Core::val($v, 'crop')) { self::crop($path, $v['class'], Core::val($v, 'width', '-'), Core::val($v, 'height', '-'), Core::val($v, 'fit', 0)); } else { self::resize($path, $v['class'], Core::val($v, 'width', '-'), Core::val($v, 'height', '-'), Core::val($v, 'fit', 0)); } } return true;}public static function delete($path) { $a = glob(dirname($path) . '/.*.' . basename($path)); foreach ($a as $v) unlink($v); unlink($path);}public static function resize($file, $class, $width='-', $height='-', $fit=0) { $a = getimagesize($file); switch ($a[2]) { case 1: $tag = 'gif'; break; case 2: $tag = 'jpeg'; break; case 3: $tag = 'png'; break; default: return; } $w = $a[0]; $h = $a[1]; if ($width == 0) { $fw = 0; $fh = $h / $height; } elseif ($height == 0) { $fw = $w / $width; $fh = 0; } else { $fw = $w / $width; $fh = $h / $height; } if (($fw == 1) and ($fh == 1)) { $file2 = dirname($file) . '/' . $class . basename($file); copy($file, $file2); return true; } elseif (($fw >= 1) and ($fh >= 1)) { if ($fw > $fh) { $w = $width; $h = floor($h / $fw); } else { $h = $height; $w = floor($w / $fh); } } elseif ($fh == 0) { if ($fw > 1) { $fit = 0; $w = $width; $h = floor($h / $fw); } else { if ($fit) { $height = $h; } } } elseif ($fw == 0) { if ($fh > 1) { $fit = 0; $w = floor($w / $fh); $h = $height; } else { if ($fit) { $width = $w; } } } elseif (($fw < 1) and ($fh < 1)) { // } elseif ($fw > $fh) { if ($fw >= 1) { $w = $width; $h = floor($h / $fw); } } elseif ($fh > $fw) { if ($fh >= 1) { $w = floor($w / $fh); $h = $height; } } if ($fit) { $x = ($width - $w) / 2; $y = ($height - $h) / 2; $cw = $width; $ch = $height; } else { $x = 0; $y = 0; $cw = $w; $ch = $h; } $file2 = dirname($file) . '/' . $class . basename($file); $f1 = 'imagecreatefrom' . $tag; $src = http://stackoverflow.com/questions/3815676/$f1($file); $new = imagecreatetruecolor($cw, $ch); return self::create($new, $src, $file2, $x, $y, $w, $h, $cw, $ch, $a);}public static function crop($file, $class, $width='-', $height='-', $fit=0) { if (!$class) exit('ExecImage: Original image can not be overwrite.'); $small = 0; $a = getimagesize($file); switch ($a[2]) { case 1: $tag = 'Gif'; break; case 2: $tag = 'Jpeg'; break; case 3: $tag = 'Png'; break; default: return; } $w = $a[0]; $h = $a[1]; if ($height == 0) { //resize by width -- height will follow $fh = 0; $fw = $w / $width; } elseif ($width == 0) { //resize by height -- width will follow $fw = 0; $fh = $h / $height; } else { $fw = $w / $width; $fh = $h / $height; } if (($fw <= 1) and ($fh <= 1)) { $small = 1; //dont resize } else { $fit = 1; //chop by the smallest if ($fh < $fw) { //Crop By Height $h = $height; $w = floor($w / $fh); //$w = $width; //$h = floor($h /$fw); //$w = $width; } else { //Crop By Width $w = $width; $h = floor($h /$fw); //$h = $height; //$w = floor($w / $fh); } } $file2 = dirname($file) . '/' . $class . basename($file); $f1 = 'ImageCreateFrom' . $tag; $src = http://stackoverflow.com/questions/3815676/$f1($file); if ($small) { if ($fit) { //image must be padded $x = ($width - $w) / 2; $y = ($height - $h) / 2; } else { //image goes as is -- shrinked $x = 0; $y = 0; } } else { //image must be centered -- this should be a square from js $x = ($width - $w) / 2; $y = ($height - $h) / 2; } if ($small) { if ($fit) { //create with the full size $new = imagecreatetruecolor($width, $height); return self::create($new, $src, $file2, $x, $y, $w, $h, $width, $height, $a); } else { //nah, just with the original size $new = imagecreatetruecolor($w, $h); return self::create($new, $src, $file2, $x, $y, $w, $h, $w, $h, $a); } } else { if ($fit) { //create with the full size $new = imagecreatetruecolor($width, $height); return self::create($new, $src, $file2, $x, $y, $w, $h, $width, $height, $a); } else { //nah, just with the original size $new = imagecreatetruecolor($w, $h); return self::create($new, $src, $file2, $x, $y, $w, $h, $w, $h, $a); } }}private static function create($new, $src, $file2, $x, $y, $w, $h, $cw, $ch, $a) { switch ($a[2]) { case 1: // GIF case 3: // PNG // http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/ // http://www.mummey.org/2008/11/transparent-gifs-with-php-and-gd/ imagealphablending($new, false); imagesavealpha($new, true); $back = imagecolorallocatealpha($new, 255, 255, 255, 127); imagefilledrectangle($new, 0, 0, $cw, $ch, $back); imagecolortransparent($new, $back); break; case 2: // JPEG $back = imagecolorallocate($new, 255, 255, 255); break; } imagefill($new, 0, 0, $back); imagecopyresampled($new, $src, $x, $y, 0, 0, $w, $h, $a[0], $a[1]); if (file_exists($file2)) unlink($file2); switch ($a[2]) { case 1: imagegif($new, $file2); break; case 2: imagejpeg($new, $file2, 100); break; case 3: imagepng($new, $file2, 0); break; } imagedestroy($src); imagedestroy($new); return true;}\[/code\]}So, any hints on how to preserve GIF transparency?
 
Back
Top