You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP图片压缩后保持原始方向的解决方案求助

解决PHP图片压缩时丢失原始拍摄方向的问题

手机拍摄的竖屏图片压缩后方向错乱,核心原因是这类图片的EXIF元数据中存储了拍摄方向信息,但原有压缩代码未读取并应用该信息,GD库默认不会自动根据EXIF方向调整图片展示角度。

修改后的完整代码

替换原有compress_image函数,加入EXIF方向校正逻辑,同时兼容原有上传流程:

$valid_formats = array("jpg","png","gif");
$max_file_size = 1024*300; //300 kb
$path = "../uploadFiles/"; // Upload directory

// 带方向校正的图片压缩函数
function compress_image($source_url, $destination_url, $quality) {
    $info = getimagesize($source_url);
    $orientation = 1; // 默认方向正常

    // 仅JPG格式读取EXIF方向信息
    if ($info['mime'] == 'image/jpeg') {
        $exif = exif_read_data($source_url);
        if (!empty($exif['Orientation'])) {
            $orientation = $exif['Orientation'];
        }
        $image = imagecreatefromjpeg($source_url);
    } elseif ($info['mime'] == 'image/gif') {
        $image = imagecreatefromgif($source_url);
    } elseif ($info['mime'] == 'image/png') {
        $image = imagecreatefrompng($source_url);
    } else {
        return false; // 不支持的格式直接返回
    }

    // 根据EXIF方向旋转图片并调整画布尺寸
    switch ($orientation) {
        case 3:
            $image = imagerotate($image, 180, 0);
            break;
        case 6:
            $image = imagerotate($image, -90, 0);
            // 旋转90度后宽高互换,更新尺寸信息
            list($width, $height) = $info;
            $info[0] = $height;
            $info[1] = $width;
            break;
        case 8:
            $image = imagerotate($image, 90, 0);
            // 旋转270度后宽高互换,更新尺寸信息
            list($width, $height) = $info;
            $info[0] = $height;
            $info[1] = $width;
            break;
    }

    // 按格式保存压缩后的图片,避免PNG失真
    if ($info['mime'] == 'image/png') {
        // PNG质量参数为0-9,对应JPG的0-100,做比例转换
        imagepng($image, $destination_url, floor($quality / 10));
    } else {
        imagejpeg($image, $destination_url, $quality);
    }
    imagedestroy($image); // 释放GD资源,避免内存泄漏
}

// 原有上传逻辑保持不变
if ($_FILES['upload']['error'][$f] != 0) {
    continue; // 跳过有错误的文件
}
if ($_FILES['upload']['error'][$f] == 0) {
    $name = $_FILES["upload"]["name"][$f];
    if(!in_array(pathinfo($name, PATHINFO_EXTENSION), $valid_formats)){
        $maimmsgs = "$name is not a valid format";
        continue; // 跳过无效格式文件
    } else {
        $emptyd = basename($_FILES["upload"]["name"][$f]);
        if($emptyd != ""){   
            if(is_uploaded_file($_FILES["upload"]["tmp_name"][$f])) {
                $file_name = "photo".rand(1000,1000000).basename($name);
                compress_image($_FILES["upload"]["tmp_name"][$f], $path.$file_name, 50);
                $count ++; // 统计成功上传文件数
            }
        }
    }
}

关键逻辑说明

  1. EXIF方向读取:仅针对JPG格式读取EXIF的Orientation字段(PNG/GIF通常不存储拍摄方向),该字段值对应不同旋转角度:
    • 3 = 180度旋转
    • 6 = 逆时针90度旋转
    • 8 = 顺时针90度旋转
  2. 画布尺寸调整:旋转90/270度后,图片宽高互换,需更新尺寸信息避免后续处理出错
  3. 格式兼容:PNG图片使用imagepng保存,避免用imagejpeg导致失真
  4. 资源释放:添加imagedestroy释放GD资源,防止内存泄漏

额外注意事项

  • 确保PHP开启exif扩展,可通过phpinfo()查看,未开启则在php.ini中添加extension=exif
  • 大尺寸图片旋转可能占用较多内存,可根据服务器配置调整PHP的memory_limit参数

内容的提问来源于stack exchange,提问作者Nany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:31:24