【问题标题】:Resizing/cropping images in PHP results in images with black border on one side在 PHP 中调整/裁剪图像会导致图像一侧带有黑色边框
【发布时间】:2015-09-01 19:51:13
【问题描述】:

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

流程:

  1. 拍摄 640x400 的图片
  2. 缩放图像以适应 450x450 画布(图像现在为 450x281)
  3. 裁剪掉多余的数据

我目前遇到的问题涉及到对于新创建的缩略图来说太小的图像(例如上面示例中提供的那个)。我希望输出具有白色背景(JPG)或透明背景(PNG)。然而,尽管我尽了最大努力,这往往会导致混乱:

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

我的代码副本:

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()

我已尝试更正透明度/颜色(在我的代码中可见),但它只影响图像的一侧。我尝试过的一切要么导致一侧具有透明/白色背景,要么两侧完全黑色。

【问题讨论】:

    标签: php image


    【解决方案1】:

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

    问题出在这里:

    $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,而我正在将imagecopyresampled 从一个位置转移到另一个位置。我找到的解决方案是完全跳过创建/使用$thmb,或者先将$proc保存为png/gif,然后将保存的图像用于imagecopyresample

    【讨论】:

      猜你喜欢
      • 2020-03-20
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      • 2011-11-18
      • 2014-10-24
      • 1970-01-01
      • 2023-03-22
      • 2012-11-22
      相关资源
      最近更新 更多