PHP实现图片压缩函数

      发布在:后端技术      评论:0 条评论
/**
 * 压缩图片并调整尺寸,保持宽高比
 * 
 * @param string $srcPath 源图片路径
 * @param string $destPath 目标图片路径
 * @param int $newWidth 最大宽度
 * @param int $newHeight 最大高度
 * @param int|null $quality 压缩质量(对JPEG/WEBP有效,范围0-100;PNG自动转换0-9)
 * @return string|false 成功返回目标路径,失败返回false
 */
function compressImage($srcPath, $destPath, $newWidth, $newHeight, $quality = null) {
    // 获取图片信息
    list($width, $height, $type) = getimagesize($srcPath);
    if ($width === null || $height === null) return false;

    // 计算等比例缩放后的尺寸(四舍五入取整)
    $ratio = min($newWidth / $width, $newHeight / $height);
    $newWidth = round($width * $ratio);
    $newHeight = round($height * $ratio);

    // 根据类型创建图像资源
    switch ($type) {
        case IMAGETYPE_JPEG:
            $srcImage = imagecreatefromjpeg($srcPath);
            break;
        case IMAGETYPE_PNG:
            $srcImage = imagecreatefrompng($srcPath);
            break;
        case IMAGETYPE_GIF:
            $srcImage = imagecreatefromgif($srcPath);
            break;
        case IMAGETYPE_WEBP:
            $srcImage = imagecreatefromwebp($srcPath);
            break;
        default:
            return false;
    }

    // 检查资源是否创建成功
    if ($srcImage === false) return false;

    // 创建新图像
    $newImage = imagecreatetruecolor($newWidth, $newHeight);
    if ($newImage === false) {
        imagedestroy($srcImage);
        return false;
    }

    // 处理透明度(PNG和GIF)
    if ($type === IMAGETYPE_PNG) {
        imagealphablending($newImage, false);
        imagesavealpha($newImage, true);
    } elseif ($type === IMAGETYPE_GIF) {
        // 保留GIF透明索引色
        $transparentIndex = imagecolortransparent($srcImage);
        if ($transparentIndex >= 0) {
            $transparentColor = imagecolorsforindex($srcImage, $transparentIndex);
            $transparentIndexNew = imagecolorallocate($newImage, $transparentColor['red'], $transparentColor['green'], $transparentColor['blue']);
            imagefill($newImage, 0, 0, $transparentIndexNew);
            imagecolortransparent($newImage, $transparentIndexNew);
        }
    }

    // 缩放图像
    imagecopyresampled($newImage, $srcImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    // 确保目标目录存在
    $destDir = dirname($destPath);
    if (!is_dir($destDir) && !mkdir($destDir, 0755, true)) {
        imagedestroy($srcImage);
        imagedestroy($newImage);
        return false;
    }

    // 保存图像(根据类型处理质量参数)
    $result = false;
    switch ($type) {
        case IMAGETYPE_JPEG:
            $quality = $quality !== null ? max(0, min(100, $quality)) : 90;
            $result = imagejpeg($newImage, $destPath, $quality);
            break;
        case IMAGETYPE_PNG:
            $compression = $quality !== null ? max(0, min(9, (int) ($quality / 11.11)) : 9; // 转换0-100到0-9
            $result = imagepng($newImage, $destPath, $compression);
            break;
        case IMAGETYPE_GIF:
            $result = imagegif($newImage, $destPath);
            break;
        case IMAGETYPE_WEBP:
            $quality = $quality !== null ? max(0, min(100, $quality)) : 80;
            $result = imagewebp($newImage, $destPath, $quality);
            break;
    }

    // 释放资源
    imagedestroy($srcImage);
    imagedestroy($newImage);

    return $result ? $destPath : false;
}

使用示例

// 压缩JPEG图片,质量设为85
$result = compressImage('input.jpg', 'output.jpg', 800, 600, 85);

// 压缩PNG图片,质量参数将转换为压缩级别
$result = compressImage('input.png', 'output.png', 800, 600, 70); // 压缩级别≈6


热门推荐