views:

18

answers:

0

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).

alt text

Any bright ideas?

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   = $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 = $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;
    }
}