PHP等比例缩放图片及剪切图片代码分享

一、等比例图片缩放函数

支持三种缩放模式:固定宽度、固定高度、按最大宽高限制缩放,可根据需求灵活调整输出尺寸。

php
/**
 * 等比例图片缩放函数
 * 支持三种缩放模式:固定宽度、固定高度、按最大宽高限制缩放
 * 兼容 GIF/JPEG/PNG 三种常见图片格式
 *
 * @param string $source_path 待处理的源图片路径
 * @param int $target_width 目标缩放宽度,默认200px
 * @param int $target_height 目标缩放高度,默认200px
 * @param string $fixed_orig 缩放模式:'width' 固定宽度等比缩放、'height' 固定高度等比缩放、空值则按最大宽高限制等比缩放
 * @return string|false 处理成功返回新图片路径,失败返回false
 */
function myImageResize(string $source_path, int $target_width = 200, int $target_height = 200, string $fixed_orig = '')
{
    // 获取源图片基础信息
    $source_info = getimagesize($source_path);
    $source_width = $source_info[0];
    $source_height = $source_info[1];
    $source_mime = $source_info['mime'];
    // 计算原图宽高比
    $ratio_orig = $source_width / $source_height;

    // 根据缩放模式计算目标尺寸
    if ($fixed_orig === 'width') {
        // 固定宽度模式:高度按原图比例计算
        $target_height = $target_width / $ratio_orig;
    } elseif ($fixed_orig === 'height') {
        // 固定高度模式:宽度按原图比例计算
        $target_width = $target_height * $ratio_orig;
    } else {
        // 最大宽高限制模式:保证输出图不超出指定宽高,且不变形
        if ($target_width / $target_height > $ratio_orig) {
            $target_width = $target_height * $ratio_orig;
        } else {
            $target_height = $target_width / $ratio_orig;
        }
    }

    // 根据图片类型创建源图像资源
    switch ($source_mime) {
        case 'image/gif':
            $source_image = imagecreatefromgif($source_path);
            break;
        case 'image/jpeg':
            $source_image = imagecreatefromjpeg($source_path);
            break;
        case 'image/png':
            $source_image = imagecreatefrompng($source_path);
            break;
        default:
            return false;
    }

    // 创建目标画布
    $target_image = imagecreatetruecolor($target_width, $target_height);
    // 重采样缩放图片
    imagecopyresampled($target_image, $source_image, 0, 0, 0, 0, $target_width, $target_height, $source_width, $source_height);

    // 生成新图片路径(默认在源文件名后拼接_new)
    $path_parts = pathinfo($source_path);
    $target_path = $path_parts['dirname'] . '/' . $path_parts['filename'] . '_new.' . $path_parts['extension'];
    
    // 输出为JPEG格式,质量100%
    imagejpeg($target_image, $target_path, 100);

    // ⚠️ 注意:原函数未内置资源释放逻辑,使用后建议手动销毁资源避免内存泄漏
    imagedestroy($source_image);
    imagedestroy($target_image);

    return $target_path;
}

缩放函数调用示例

php
// 1. 限制最大宽高200px,等比缩放(不会超出200*200的范围)
myImageResize($sourcePath, 200, 200);

// 2. 固定宽度200px,高度自动按原图比例适配
myImageResize($sourcePath, 200, 200, 'width');

// 3. 固定高度200px,宽度自动按原图比例适配
myImageResize($sourcePath, 200, 200, 'height');

二、固定尺寸居中裁剪函数

先按目标宽高比从源图居中裁剪匹配比例的区域,再缩放到指定尺寸,保证输出图片无变形,适合生成头像、封面等固定尺寸场景。

php
/**
 * 固定尺寸居中裁剪函数
 * 先按目标宽高比从源图居中裁剪匹配比例的区域,再缩放到指定尺寸,避免输出图片变形
 * 兼容 GIF/JPEG/PNG 三种常见图片格式
 *
 * @param string $source_path 待处理的源图片路径
 * @param int $target_width 目标输出宽度
 * @param int $target_height 目标输出高度
 * @return bool 处理成功返回true,失败返回false
 */
function imagecropper(string $source_path, int $target_width, int $target_height): bool
{
    // 获取源图片基础信息
    $source_info = getimagesize($source_path);
    $source_width = $source_info[0];
    $source_height = $source_info[1];
    $source_mime = $source_info['mime'];
    // 计算源图、目标图的宽高比
    $source_ratio = $source_height / $source_width;
    $target_ratio = $target_height / $target_width;

    // 计算需要裁剪的区域坐标和尺寸
    if ($source_ratio > $target_ratio) {
        // 源图高宽比大于目标比例:源图更高,需要上下裁剪多余部分
        $cropped_width = $source_width;
        $cropped_height = $source_width * $target_ratio;
        $source_x = 0;
        $source_y = ($source_height - $cropped_height) / 2; // 居中裁剪
    } elseif ($source_ratio < $target_ratio) {
        // 源图高宽比小于目标比例:源图更宽,需要左右裁剪多余部分
        $cropped_width = $source_height / $target_ratio;
        $cropped_height = $source_height;
        $source_x = ($source_width - $cropped_width) / 2; // 居中裁剪
        $source_y = 0;
    } else {
        // 源图比例与目标一致,无需额外裁剪
        $cropped_width = $source_width;
        $cropped_height = $source_height;
        $source_x = 0;
        $source_y = 0;
    }

    // 根据图片类型创建源图像资源
    switch ($source_mime) {
        case 'image/gif':
            $source_image = imagecreatefromgif($source_path);
            break;
        case 'image/jpeg':
            $source_image = imagecreatefromjpeg($source_path);
            break;
        case 'image/png':
            $source_image = imagecreatefrompng($source_path);
            break;
        default:
            return false;
    }

    // 创建目标画布和临时裁剪画布
    $target_image = imagecreatetruecolor($target_width, $target_height);
    $cropped_image = imagecreatetruecolor($cropped_width, $cropped_height);

    // 第一步:从源图裁剪出匹配比例的区域
    imagecopy($cropped_image, $source_image, 0, 0, $source_x, $source_y, $cropped_width, $cropped_height);
    // 第二步:将裁剪后的区域缩放到目标尺寸
    imagecopyresampled($target_image, $cropped_image, 0, 0, 0, 0, $target_width, $target_height, $cropped_width, $cropped_height);

    // 生成新图片路径(默认在源文件名后拼接_small)
    $dotpos = strrpos($source_path, '.');
    $imgName = substr($source_path, 0, $dotpos);
    $suffix = substr($source_path, $dotpos);
    $imgNew = $imgName . '_small' . $suffix;

    // 输出图片
    imagejpeg($target_image, $imgNew, 100);

    // 释放所有图像资源
    imagedestroy($source_image);
    imagedestroy($target_image);
    imagedestroy($cropped_image);

    return true;
}

裁剪函数调用示例

php
// 将任意尺寸的图片裁剪为200*200px的正方形,自动居中取图
imagecropper($sourcePath, 200, 200);

注意事项

  1. 以上函数依赖PHP GD扩展,使用前请确认环境已开启该扩展
  2. 处理大尺寸图片时建议适当调整PHP内存限制(memory_limit),避免报内存不足错误
  3. 缩放函数的路径拼接逻辑基于文件名仅含一个后缀的场景,如果源路径包含多个点(如test.demo.jpg),需要自行调整路径拼接逻辑避免出错
  4. 生产环境使用时建议增加文件类型校验、路径权限检查等逻辑,避免安全风险
© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论