代码之家  ›  专栏  ›  技术社区  ›  TRiG

重建缩略图时保留GIF稀疏性

  •  0
  • TRiG  · 技术社区  · 16 年前

    如果我得到的是一个完全黑色或透明的填充物,我会知道问题出在哪里,但我得到的填充物在某些地方是透明的,在其他地方是黑色的,这是没有意义的。

    PNG和GIF图像示例 http://filedump.xn--es-zka.info/broken_thumbs/ (背景颜色为令人震惊的粉色,这样你就可以看到白色和透明的区别)。

    alt text

    有什么好主意吗?

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

    要添加的修订/编辑:

    好吧,我已经解决了主要问题:添加到PNG或GIF图像的填充现在是透明的,而不是黑色的。小问题,即GIF透明度变黑,仍然与我们,但我不太使用GIF透明度。

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

    那么,关于如何保持GIF透明度有什么提示吗?

    1 回复  |  直到 15 年前
        1
  •  0
  •   Shikiryu DhruvJoshi    15 年前

    你把 a link 带着你的答案;)

    你用的是 imageCopyResampled 阿尔法的行为很奇怪。使用 imageCopyResized 相反。

    http://www.mummey.org/2008/11/transparent-gifs-with-php-and-gd/comment-page-1/#comment-94