1

我创建了一个函数,它根据参数以不同的方式处理图像。我在函数中有注释来解释一下。

当我拍摄 jpg 图像并将其保存为 png 时,一切正常。我刚刚检查过,即使我使用imagepng()但使用扩展名 .jpg 保存它,图像在正确调整大小时显示,但扩展名为 .jpg。但是,如果我上传相同的 .jpg 图像,使用imagepng()并使用 .png 扩展名保存它,我会在调整大小后以 png 格式获得预期宽度和高度的图像,并带有 .png 扩展名。虽然整个图像是 100% 透明的,但我在左上角有一个 1px x 1px 黑色像素。

如果有人能看看这个,看看他们是否看到我遗漏的东西,我将不胜感激。我相信 1px X 1px 来自我用于 的点imagefill(),但我不明白为什么;它应该像图像的其余部分一样填充所有透明。

这是我的功能:

if(!function_exists("upload")){
    //$image = $image file name
    //$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
    //$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
    //$proportion = 2,1,0;
    //------ 2 = Preserve proportions while adding a border to fill width and height  
    //------ 1 = retain proportion to fit within both given width and height
    //------ 0 = disregard proportions and resize to the exact width and height
    function upload($image, $width, $height, $proportion){
        // IS GD HERE?

        $gdv = get_gd_info();

        if (!$gdv){ 
            return FALSE;
        }

        // GET AN IMAGE THING

        $ext = trim(strtolower(end(explode('.', $image))));

        list($imageX, $imageY, $type) = getimagesize($image);   //gets information about new server image

        // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
        $ratio_w = ($width / $imageX);
        $ratio_h = ($height / $imageY);
        $ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;     

        if($width == 0){

            if($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;    
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }

            $width = $newWidth;
            $height = $newHeight;

            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;

        }elseif($height == 0){

            if ($imageX > $width){
                $newWidth = $width;
                $newHeight = ($width/$imageX) * $imageY;
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }

            $width = $newWidth;
            $height = $newHeight;

            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;

        }elseif($proportion == 2){

            // COMPUTE THUMBNAIL IMAGE DIMENSIONS
            $newWidth = $imageX * $ratio;
            $newHeight = $imageY * $ratio;

            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = ($width - $newWidth) / 2.0;
            $fromMidY = ($height - $newHeight) / 2.0;

        }elseif($proportion == 1){

            if ($imageX > $width){
                $newHeight = ($width/$imageX) * $imageY;
                $newWidth = $width;
            }
            if ($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;
            }

            $fromMidY = 0;
            $fromMidX = 0;

        }elseif($proportion == 0){

            $newWidth = $width;
            $newHeight = $height;

            $fromMidY = 0;
            $fromMidX = 0;          
        }

        switch(strtoupper($ext))
        {
            case 'JPG' :
            case 'JPEG' :
                $source = imagecreatefromjpeg($image);
                break;

            case 'PNG' :
                $source = imagecreatefrompng($image);

                break;

            default : die("UNKNOWN IMAGE TYPE: $image");
        }

        // WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
        if ($gdv >= 2)
        {

            // IF GD IS AT LEVEL 2 OR ABOVE
            $target = imagecreatetruecolor($width, $height);
            $color = imagecolorallocatealpha($target, 0, 0, 0, 127); 

            imagefill($target, 0, 0, $color);

            imagesavealpha($target, TRUE);


            imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);

        }
        else
        {
            // IF GD IS AT A LOWER REVISION LEVEL
            $target = imagecreate($width, $height);
            imagesavealpha($target, TRUE);
                $empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
                imagefill($target, 0, 0, $empty);
            imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
        }

        // SHARPEN THE PIC
        $sharpenMatrix = array
        ( array( -1.2, -1, -1.2 )
        , array( -1,   20, -1 )
        , array( -1.2, -1, -1.2 )
        )
        ;
        $divisor = array_sum(array_map('array_sum', $sharpenMatrix));
        $offset  = 0;
        imageconvolution($target, $sharpenMatrix, $divisor, $offset);

        if(imagepng($target, $image,9)){

            imagedestroy($target);
        }else{

        }

        return $image;  
    }
}

编辑1:我想我应该注意到我正在上传一个.jpg图像(例如:100px X 200px)并将它们转换为.png(例如:400px X 200px),但我保留了图像的比例以完全适合目标 .png 的中心。所以我会有一个 400px X 200px .p​​ng,我的图像在中心,左右 100px,应该是透明的。这样它就可以很好地适合没有纯色作为填充的滑块。所以我调用我的函数的一个例子是upload($image, 400, 200, 2).

4

1 回答 1

0

我弄清楚了问题所在。决定我是否应该使用imagecreatefromjpegimagecreatefrompng错误地离开传递图像的扩展名的代码部分,而不是它的 mime 类型。我把它改成这样:

switch($type)
        {
            case '2' :
                $source = imagecreatefromjpeg($image);
                break;
            case '3' :
                $source = imagecreatefrompng($image);
                break;
            default : die("UNKNOWN IMAGE TYPE: $image");
        }

我在那里$type的线路来自哪里

list($imageX, $imageY, $type) = getimagesize($image);

所以所有的功能是:

if(!function_exists("upload")){
    //$image = $image file name
    //$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
    //$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
    //$proportion = 2,1,0;
    //------ 2 = Preserve proportions while adding a border to fill width and height  
    //------ 1 = retain proportion to fit within both given width and height
    //------ 0 = disregard proportions and resize to the exact width and height


    function upload($image, $width, $height, $proportion){
        // IS GD HERE?

        $gdv = get_gd_info();

        if (!$gdv){ 
            return FALSE;
        }

        // GET AN IMAGE THING

        $ext = trim(strtolower(end(explode('.', $image))));

        list($imageX, $imageY, $type) = getimagesize($image);   //gets information about new server image

        // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
        $ratio_w = ($width / $imageX);
        $ratio_h = ($height / $imageY);
        $ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;     

        if($width == 0){

            if($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;    
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }

            $width = $newWidth;
            $height = $newHeight;

            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;

        }elseif($height == 0){

            if ($imageX > $width){
                $newWidth = $width;
                $newHeight = ($width/$imageX) * $imageY;
            }else{
                $newHeight = $imageY;
                $newWidth = $imageX;    
            }

            $width = $newWidth;
            $height = $newHeight;

            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = 0;
            $fromMidY = 0;

        }elseif($proportion == 2){

            // COMPUTE THUMBNAIL IMAGE DIMENSIONS
            $newWidth = $imageX * $ratio;
            $newHeight = $imageY * $ratio;

            // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
            $fromMidX = ($width - $newWidth) / 2.0;
            $fromMidY = ($height - $newHeight) / 2.0;

        }elseif($proportion == 1){

            if ($imageX > $width){
                $newHeight = ($width/$imageX) * $imageY;
                $newWidth = $width;
            }
            if ($imageY > $height){
                $newHeight = $height;
                $newWidth = ($height/$imageY) * $imageX;
            }

            $fromMidY = 0;
            $fromMidX = 0;

        }elseif($proportion == 0){

            $newWidth = $width;
            $newHeight = $height;

            $fromMidY = 0;
            $fromMidX = 0;          
        }

        switch($type)
        {
            case '2' :
                $source = imagecreatefromjpeg($image);
                break;
            case '3' :
                $source = imagecreatefrompng($image);
                break;
            default : die("UNKNOWN IMAGE TYPE: $image");
        }

        // WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
        if ($gdv >= 2)
        {

            // IF GD IS AT LEVEL 2 OR ABOVE
            $target = imagecreatetruecolor($width, $height);
            $color = imagecolorallocatealpha($target, 0, 0, 0, 127); 
            imagefill($target, 0, 0, $color);
            imagesavealpha($target, TRUE);
            imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);

        }
        else
        {
            // IF GD IS AT A LOWER REVISION LEVEL
            $target = imagecreate($width, $height);
            imagesavealpha($target, TRUE);
                $empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
                imagefill($target, 0, 0, $empty);
            imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
        }

        // SHARPEN THE PIC
        $sharpenMatrix = array
        ( array( -1.2, -1, -1.2 )
        , array( -1,   20, -1 )
        , array( -1.2, -1, -1.2 )
        )
        ;
        $divisor = array_sum(array_map('array_sum', $sharpenMatrix));
        $offset  = 0;
        imageconvolution($target, $sharpenMatrix, $divisor, $offset);

        if(imagepng($target, $image,9)){
            imagedestroy($target);
        }
        return $image;
    }
}

一个示例调用是:upload("path/to/image/on/server.png", 400, 200, 2) 其中图像路径可以是 jpg 或 png mime 类型。但扩展名必须是 .png。我想我可以让它更聪明,你可以有任何扩展,但是对于使用这个函数的当前代码,让我保持原样更有意义。我想最终添加打开或关闭透明度的选项,并在需要时使用纯色,例如黑色。随意使用和修改它。

我计划在这里使用一些不错的 hex2rgb/rgb2hex 函数

于 2013-01-11T14:59:24.307 回答