外贸网站建设,外贸网站建设公司,跨境电商独立站

PB在某个栏目点击某个分页的时候程序运行异常: imagecopyresampled():

时间:2026-11-03   访问量:1013

略图中有 WebP 图片,但

[list:ico  width=300 height=200]

裁剪函数只支持 GIF、JPEG、PNG。遇到 WebP 时没有创建源图像,PHP 8 就在第 533 行报错。我会补上 WebP 读写支持,并检查图片读取失败的情况,避免单张异常图片导致整页无法打开。


修复方案:

core/function/file.php中的以下函数修改:

/**
 * *
 * 等比缩放图片
 *
 * @param string $src_image源图片路径
 * @param string $out_image输出图像路径
 * @param number $max_width最大宽
 * @param number $max_height最大高
 * @param number $img_quality图片质量
 * @return boolean 返回是否成功
 */
function resize_img($src_image, $out_image = null, $max_width = null, $max_height = null, $img_quality = 90)
{
    // 输出地址
    if (! $out_image)
        $out_image = $src_image;
    
    // 读取配置文件设置
    if (! $max_width)
        $max_width = Config::get('upload.max_width') ?: 999999999;
    if (! $max_height)
        $max_height = Config::get('upload.max_height') ?: 999999999;
    
    // 获取图片属性
    $image_info = @getimagesize($src_image);
    if (! $image_info || $image_info[0] < 1 || $image_info[1] < 1) {
        return false;
    }
    list ($width, $height, $type) = $image_info;
    
    // 检查输出目录
    check_dir(dirname($out_image), true);
    
    // 无需缩放的图片
    if ($width <= $max_width && $height <= $max_height) {
        if ($src_image != $out_image) { // 存储地址不一致时进行拷贝
            if (! copy($src_image, $out_image)) {
                return '缩放图片时拷贝到目的地址失败!';
            }
        }
        return true;
    }
    
    // 求缩放比例
    if ($max_width && $max_height) {
        $scale = min($max_width / $width, $max_height / $height);
    } elseif ($max_width) {
        $scale = $max_width / $width;
    } elseif ($max_height) {
        $scale = $max_height / $height;
    }
    
    if ($scale < 1) {
        switch ($type) {
            case 1:
                $img = @imagecreatefromgif($src_image);
                break;
            case 2:
                $img = @imagecreatefromjpeg($src_image);
                break;
            case 3:
                $img = @imagecreatefrompng($src_image);
                break;
            case 18: // WebP
                if (! function_exists('imagecreatefromwebp') || ! function_exists('imagewebp')) {
                    return false;
                }
                $img = @imagecreatefromwebp($src_image);
                break;
            default:
                return false;
        }
        if (! $img) {
            return false;
        }
        
        $new_width = max(1, (int) floor($scale * $width));
        $new_height = max(1, (int) floor($scale * $height));
        $new_img = imagecreatetruecolor($new_width, $new_height); // 创建画布
                                                                  
        // 创建透明画布,避免黑色
        if ($type == 18 || $type == 3) {
            imagealphablending($new_img, false);
            imagesavealpha($new_img, true);
            imagefill($new_img, 0, 0, imagecolorallocatealpha($new_img, 0, 0, 0, 127));
        } elseif ($type == 1) {
            $color = imagecolorallocate($new_img, 255, 255, 255);
            imagefill($new_img, 0, 0, $color);
            imagecolortransparent($new_img, $color);
        }
        imagecopyresized($new_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
        
        switch ($type) {
            case 1:
                imagegif($new_img, $out_image); // GIF不支持质量参数,所以只传递两个参数 @LiuXiaoBai
                break;
            case 2:
                imagejpeg($new_img, $out_image, $img_quality);
                break;
            case 3:
                imagepng($new_img, $out_image, max(0, min(9, (int) ($img_quality / 10))));
                break;
            case 18:
                imagewebp($new_img, $out_image, max(0, min(100, (int) $img_quality)));
                break;
            default:
                imagejpeg($new_img, $out_image, $img_quality);
        }
        imagedestroy($new_img);
        imagedestroy($img);
    }
    return true;
}

// 剪切图片
function cut_img($src_image, $out_image = null, $new_width = null, $new_height = null, $img_quality = 90)
{
    // 输出地址
    if (! $out_image)
        $out_image = $src_image;
    
    // 读取配置文件设置
    if (! $new_width && ! $new_height)
        return;
    
    // 获取图片属性
    $image_info = @getimagesize($src_image);
    if (! $image_info || $image_info[0] < 1 || $image_info[1] < 1) {
        return false;
    }
    list ($width, $height, $type) = $image_info;
    switch ($type) {
        case 1:
            $img = @imagecreatefromgif($src_image);
            break;
        case 2:
            $img = @imagecreatefromjpeg($src_image);
            break;
        case 3:
            $img = @imagecreatefrompng($src_image);
            break;
        case 18: // WebP
            if (! function_exists('imagecreatefromwebp') || ! function_exists('imagewebp')) {
                return false;
            }
            $img = @imagecreatefromwebp($src_image);
            break;
        default:
            return false;
    }
    if (! $img) {
        return false;
    }
    if (($new_width !== null && (! is_numeric($new_width) || $new_width < 0)) ||
        ($new_height !== null && (! is_numeric($new_height) || $new_height < 0))) {
        imagedestroy($img);
        return false;
    }
    
    // 不限定是等比例缩放
    if (! $new_width) {
        $new_width = floor($width * ($new_height / $height));
    }
    if (! $new_height) {
        $new_height = floor($height * ($new_width / $width));
    }
    $new_width = max(1, (int) $new_width);
    $new_height = max(1, (int) $new_height);
    // 创建画布
    $new_img = imagecreatetruecolor($new_width, $new_height);
    
    // 创建透明画布,避免黑色
    if ($type == 18 || $type == 3) {
        imagealphablending($new_img, false);
        imagesavealpha($new_img, true);
        imagefill($new_img, 0, 0, imagecolorallocatealpha($new_img, 0, 0, 0, 127));
    } elseif ($type == 1) {
        $color = imagecolorallocate($new_img, 255,255,255);
        imagecolortransparent($new_img, $color);
        imagefill($new_img, 0, 0, $color);
    }


    // 先缩放
    $scale = max($new_width / $width, $new_height / $height);
    $scale_width = max($new_width, (int) ceil($scale * $width));
    $scale_height = max($new_height, (int) ceil($scale * $height));
    $scale_img = imagecreatetruecolor($scale_width, $scale_height); // 创建画布
    
    // 缩放后将图像设置为透明,避免黑色
    if ($type == 18 || $type == 3) {
        imagealphablending($scale_img, false);
        imagesavealpha($scale_img, true);
        imagefill($scale_img, 0, 0, imagecolorallocatealpha($scale_img, 0, 0, 0, 127));
    } elseif ($type == 1) {
        $color = imagecolorallocate($scale_img, 255,255,255);
        imagecolortransparent($scale_img, $color);
        imagefill($scale_img, 0, 0, $color);
    }
    
    if(function_exists("ImageCopyResampled")) {
       imagecopyresampled($scale_img, $img, 0, 0, 0, 0, $scale_width, $scale_height, $width, $height);
    } else {
       imagecopyresized($scale_img, $img, 0, 0, 0, 0, $scale_width, $scale_height, $width, $height);
    }
    //再裁剪
    $start_x = (int) floor(($scale_width - $new_width) / 2);
    $start_y = (int) floor(($scale_height - $new_height) / 2);

    //拷贝剪切的图像数据到画板,生成剪切图像
    imagecopy($new_img, $scale_img, 0, 0, $start_x, $start_y, $new_width, $new_height);

    check_dir(dirname($out_image), true); // 检查输出目录
    
    switch ($type) {
        case 1:
            $saved = imagegif($new_img, $out_image);
            break;
        case 2:
            $saved = imagejpeg($new_img, $out_image, $img_quality);
            break;
        case 3:
            $saved = imagepng($new_img, $out_image, max(0, min(9, (int) ($img_quality / 10))));
            break;
        case 18:
            $saved = imagewebp($new_img, $out_image, max(0, min(100, (int) $img_quality)));
            break;
        default:
            imagejpeg($new_img, $out_image, $img_quality);
    }
    imagedestroy($scale_img);
    imagedestroy($new_img);
    imagedestroy($img);
    return $saved;
}


正在加载评论…