Сохранение прозрачности GIF при восстановлении миниатюр - PullRequest
0 голосов
/ 28 сентября 2010

При загрузке изображений код создает несколько разных миниатюр.В некоторых случаях миниатюра может быть больше исходного изображения, и в этом случае применяется дополнение.В случае с JPEG, отступы белые, и все хорошо.В случае GIF и PNG отступы должны быть прозрачными.И это.Или нет.Что странно.

Если бы я получал полностью черный или прозрачный отступ, у меня была бы некоторая идея, в чем проблема, но я получаю отступы, которые прозрачны в некоторых местах и ​​черные в других, что делаетнет смысла.

Образцы изображений 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 Ответ

0 голосов
/ 14 января 2011

Вы ставите ссылку с вашим ответом;)

Вы используете imageCopyResampled, что странно с альфой.Вместо этого используйте imageCopyResized.

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

...