在PHP中调整/裁剪图像会导致图像一侧带有黑色边框

在PHP中调整/裁剪图像会导致图像一侧带有黑色边框,php,image,Php,Image,我创建了一个函数,可以拍摄图像,调整它们的大小,使其至少适合画布上的一个维度,最后裁剪出多余的图像内容 过程: 拍摄一张640x400的图像 将图像缩放到450x450画布(图像现在为450x281) 裁剪出多余的数据(如果有) 我目前遇到的问题是,对于新创建的缩略图而言,图像太小(如上面示例中提供的图像)。我希望输出有白色背景(JPGs)或透明背景(PNGs)。然而,尽管我尽了最大的努力,这往往会导致混乱: 可以观察到,图像具有黑色背景,而不是透明/白色背景。我完全不知道如何纠正这个缺陷 我

我创建了一个函数,可以拍摄图像,调整它们的大小,使其至少适合画布上的一个维度,最后裁剪出多余的图像内容

过程:

  • 拍摄一张640x400的图像
  • 将图像缩放到450x450画布(图像现在为450x281)
  • 裁剪出多余的数据(如果有)
  • 我目前遇到的问题是,对于新创建的缩略图而言,图像太小(如上面示例中提供的图像)。我希望输出有白色背景(JPGs)或透明背景(PNGs)。然而,尽管我尽了最大的努力,这往往会导致混乱:

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

    我的代码副本:

    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()
    
    函数创建缩略图($path、$saveto、$width、$height){
    ini_set('memory_limit','128M');//解锁更多内存以供下载
    $info=getimagesize($path);
    $rate=$info[0]/$info[1];
    //确定图像大小/位置
    如果($info[0]<$width | |$info[1]<$height){
    //图像太小
    如果($info[0]<$width&$info[1]<$height){
    //宽度和高度都太小
    $nw=$info[0];
    $nh=$info[1];
    }else if($info[0]<$width){
    //宽度太小
    $nw=($info[0]*$height)/$info[1];
    $nh=$height;
    }else if($info[1]<$height){
    //高度太小了
    $nw=$width;
    $nh=($info[1]*$width)/$info[0];
    }
    }否则{
    //图像匹配
    如果(($width/$height)>$rate){
    $nw=$width;
    $nh=$width/$rate;
    }否则{
    $nw=$height*$rate;
    $nh=$height;
    }
    }
    $nw=圆形($nw);
    $nh=圆形($nh);
    $x_mid=圆形($nw/2);
    $y_mid=圆形($nh/2);
    交换机($info[2]){
    案例IMAGETYPE_PNG:
    $src=imagecreatefrompng($path);
    打破
    case IMAGETYPE_JPEG:
    $src=imagecreatefromjpeg($path);
    打破
    案例图像类型\u GIF:
    $src=imagecreatefromformgif($path);
    打破
    违约:
    返回false;
    }
    //创造形象
    $proc=ImageCreateTureColor($nw,$nh);
    $clr=imagecolorallocate($proc,255,255,255);
    imagefill($proc,0,0,$clr);
    imagecopyresampled($proc、$src、0、0、0、$nw、$nh、$info[0]、$info[1]);
    $thmb=ImageCreateTureColor($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);
    如果($info[2]==IMAGETYPE_PNG | |$info[2]==IMAGETYPE_GIF){
    $trnprt_idx=imagecolortransparent($src);
    如果($trnprt\u idx>=0){
    //尝试使用原始图像的颜色索引强制校正透明度
    $trnprt_clr=imagecolorsforindex($src,$trnprt_idx);
    $trnprt_idx=imagecolorallocate($thmb、$trnprt_clr['red']、$trnprt_clr['green']、$trnprt_clr['blue']);
    图像填充($thmb,0,0,$trnprt_idx);
    imagecolortransparent($thmb,$trnprt_idx);
    imagealphablending($thmb,false);
    imagesavealpha($thmb,true);
    }else if($info[2]==IMAGETYPE\u PNG){
    //尝试通过关闭混合来强制更正透明度
    $clr=imagecolorallocatealpha($thmb,0,0,0127);
    imagefill($thmb,0,0,$clr);
    imagealphablending($thmb,false);
    imagesavealpha($thmb,true);
    }
    }
    交换机($info[2]){
    案例IMAGETYPE_PNG:
    imagepng($thmb,$saveto);
    打破
    case IMAGETYPE_JPEG:
    imagejpeg($thmb,$saveto,100);
    打破
    案例图像类型\u GIF:
    imagegif($thmb,$saveto);
    打破
    违约:
    返回false;
    }
    返回true;
    }//创建_缩略图()的结束
    

    我试图纠正透明度/颜色(在我的代码中可见),但它只影响图像的一侧。我尝试过的每一件事都会导致一面有一个透明/白色的背景,或者两面都是完全黑色的。

    在花了很长时间试图弄清楚到底发生了什么和破坏了什么之后,我找到了解决办法

    问题在于:

    $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);
    

    当我从一个图像重新采样到另一个图像时,新创建的图像
    $proc
    没有将其透明度转移到
    $thmb
    。我找到的解决方案是跳过创建/使用
    $thmb
    ,或者先将
    $proc
    保存为png/gif,然后将保存的图像用于
    imagecopyresample

    在花了很长时间试图弄清楚到底发生了什么和破坏了什么之后,我找到了解决方案

    问题在于:

    $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);
    

    当我从一个图像重新采样到另一个图像时,新创建的图像
    $proc
    没有将其透明度转移到
    $thmb
    。我找到的解决方案是跳过创建/使用
    $thmb
    ,或者先将
    $proc
    保存为png/gif,然后将保存的图像用于
    imagecopyresample

    在花了很长时间试图弄清楚到底发生了什么和破坏了什么之后,我找到了解决方案

    问题在于:

    $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);
    
    当我从一个图像重新采样到另一个图像时,新创建的图像
    $proc
    没有将其透明度转移到
    $thmb
    。我找到的解决方案是跳过创建/使用
    $thmb