在PHP中调整图像大小/裁剪图像会在一侧生成带有黑色边框的图像

时间:2015-09-01 19:51:13

标签: php image

我创建了一个获取图像的功能,调整它们的大小以使至少一个维度完美地适应画布,最后裁剪掉多余的图像内容。

过程:

  1. 拍摄640x400图像
  2. 缩放图像适合450x450画布(图像现在为450x281)
  3. 裁剪多余数据(如果有)
  4. 我遇到的问题目前涉及的图像对于新创建的缩略图来说太小(例如上面示例中提供的图像)。我希望输出具有白色背景(JPG)或透明背景(PNG)。然而,尽管我付出了最大的努力,但这往往是造成的混乱:

    Broken image

    可以观察到,图像具有黑色背景而不是透明/白色背景。我完全不知道如何纠正这个缺陷。

    我的代码副本:

    function create_thumbnail($path, $saveto, $width, $height) {
        ini_set('memory_limit', '128M');    //Unlocking more memory for download
        $info = getimagesize($path);
        $rate = $info[0]/$info[1];
    
        // Determine image size/position
        if ($info[0] < $width || $info[1] < $height) {
            // Image is too small
            if ($info[0] < $width && $info[1] < $height) {
                // Both width and height too small
                $nw = $info[0];
                $nh = $info[1];
            } else if ($info[0] < $width) {
                // Width is too small
                $nw = ($info[0]*$height)/$info[1];
                $nh = $height;
            } else if ($info[1] < $height) {
                // Height is too small
                $nw = $width;
                $nh = ($info[1]*$width)/$info[0];
            }
        } else {
            // Image fits
            if (($width/$height) > $rate) {
                $nw = $width;
                $nh = $width/$rate;
            } else {
                $nw = $height*$rate;
                $nh = $height;
            }
        }
    
        $nw = round($nw);
        $nh = round($nh);
    
        $x_mid = round($nw/2);
        $y_mid = round($nh/2);
    
        switch($info[2]) {
            case IMAGETYPE_PNG :
                $src = imagecreatefrompng($path);
                break;
            case IMAGETYPE_JPEG :
                $src = imagecreatefromjpeg($path);
                break;
            case IMAGETYPE_GIF :
                $src = imagecreatefromgif($path);
                break;
            default :
                return false;
        }
    
        // Create image
        $proc = imagecreatetruecolor($nw, $nh);
        $clr = imagecolorallocate($proc, 255, 255, 255);
        imagefill($proc, 0, 0, $clr);
        imagecopyresampled($proc, $src,  0, 0, 0, 0, $nw, $nh, $info[0], $info[1]);
    
        $thmb = imagecreatetruecolor($width, $height);
        $clr = imagecolorallocate($thmb, 255, 255, 255);
        imagefill($thmb, 0, 0, $clr);
        imagecopyresampled($thmb, $proc, 0, 0, ($x_mid-($width/2)), ($y_mid-($height/2)), $width, $height, $width, $height);
    
        if ($info[2] == IMAGETYPE_PNG || $info[2] == IMAGETYPE_GIF) {
            $trnprt_idx = imagecolortransparent($src);
    
            if ($trnprt_idx >= 0) {
                // Attempt to forcefully correct transparencies using original image's color index
                $trnprt_clr = imagecolorsforindex($src, $trnprt_idx);
                $trnprt_idx = imagecolorallocate($thmb, $trnprt_clr['red'], $trnprt_clr['green'], $trnprt_clr['blue']);
                imagefill($thmb, 0, 0, $trnprt_idx);
                imagecolortransparent($thmb, $trnprt_idx);
    
                imagealphablending($thmb, false);
                imagesavealpha($thmb, true);
            } else if ($info[2] == IMAGETYPE_PNG) {
                // Attempt to forcefully correct transparencies by shutting down blending
                $clr = imagecolorallocatealpha($thmb, 0, 0, 0, 127);
                imagefill($thmb, 0, 0, $clr);
                imagealphablending($thmb, false);
                imagesavealpha($thmb, true);
            }
        }
    
        switch($info[2]) {
            case IMAGETYPE_PNG :
                imagepng($thmb, $saveto);
                break;
            case IMAGETYPE_JPEG :
                imagejpeg($thmb, $saveto, 100);
                break;
            case IMAGETYPE_GIF :
                imagegif($thmb, $saveto);
                break;
            default :
                return false;
        }
    
        return true;
    } //End of create_thumbnail()
    

    我试图纠正透明度/着色(在我的代码中可见),但它只影响图像的一侧。我尝试的所有东西要么导致一面具有透明/白色背景,要么两面都是完全黑色。

1 个答案:

答案 0 :(得分:2)

经过长时间的游戏,试图弄清楚到底发生了什么,我发现了解决方案。

问题在于:

$proc = imagecreatetruecolor($nw, $nh);
$clr = imagecolorallocate($proc, 255, 255, 255);
imagefill($proc, 0, 0, $clr);
imagecopyresampled($proc, $src,  0, 0, 0, 0, $nw, $nh, $info[0], $info[1]);

$thmb = imagecreatetruecolor($width, $height);
$clr = imagecolorallocate($thmb, 255, 255, 255);
imagefill($thmb, 0, 0, $clr);
imagecopyresampled($thmb, $proc, 0, 0, ($x_mid-($width/2)), ($y_mid-($height/2)), $width, $height, $width, $height);

当我从{1}}进行$proc时,新创建的图片$thmb未将其透明度转移到imagecopyresampled。我找到的解决方案是要么完全跳过创建/使用$thmb,要么先将$proc保存为png / gif,然后将保存的图像用于imagecopyresample