如何使用PHP调整上传图片尺寸为256px×256px?
问题核心原因
- 你代码中存在逻辑顺序错误:先用
imagepng/imagejpeg将调整好尺寸的256×256图片写入了目标路径$promolink,紧接着又调用move_uploaded_file将未做任何处理的原始上传文件覆盖了该路径,前面的图片缩放逻辑完全被覆盖,最终保存的还是原图,自然尺寸不符合预期。 - 额外还存在多个潜在问题:仅支持jpg、png两种格式,传入其他格式会直接报错;仅通过文件名后缀判断图片格式,可靠性极低;直接拉伸缩放会导致图片比例失衡变形;未判断存储目录是否存在,目录不存在时写入会失败;没有释放图片处理过程中占用的内存。
可行修复方案
首先删除多余的move_uploaded_file调用,再补充异常判断、比例适配、格式兼容等逻辑即可,修复后的参考代码如下:
if(isset($_FILES['promo_image']) && $_FILES['promo_image']['error'] === UPLOAD_ERR_OK) { // 定义存储目录,提前判断是否存在,不存在则创建 $saveDir = "uploads/Image/"; if (!file_exists($saveDir)) { mkdir($saveDir, 0755, true); } // 从临时文件读取真实格式,不依赖文件名后缀 $tmpPath = $_FILES['promo_image']['tmp_name']; $imageInfo = getimagesize($tmpPath); if (!$imageInfo) { // 非合法图片直接终止 exit("上传文件不是合法图片"); } $mime = $imageInfo['mime']; $width = $imageInfo[0]; $height = $imageInfo[1]; // 根据真实mime创建图片资源,支持常见格式 switch ($mime) { case 'image/jpeg': $original = imagecreatefromjpeg($tmpPath); $ext = 'jpg'; break; case 'image/png': $original = imagecreatefrompng($tmpPath); $ext = 'png'; break; case 'image/webp': $original = imagecreatefromwebp($tmpPath); $ext = 'webp'; break; default: exit("不支持的图片格式"); } // 计算等比缩放坐标,避免图片拉伸变形 $targetSize = 256; $srcX = $srcY = 0; $srcW = $width; $srcH = $height; if ($width > $height) { $srcX = ($width - $height) / 2; $srcW = $height; } else { $srcY = ($height - $width) / 2; $srcH = $width; } // 创建画布处理透明通道 $resized = imagecreatetruecolor($targetSize, $targetSize); if ($mime == 'image/png' || $mime == 'image/webp') { imagealphablending($resized, false); imagesavealpha($resized, true); $transparent = imagecolorallocatealpha($resized, 255, 255, 255, 127); imagefill($resized, 0, 0, $transparent); } // 裁剪+缩放 imagecopyresampled($resized, $original, 0, 0, $srcX, $srcY, $targetSize, $targetSize, $srcW, $srcH); // 生成文件名,避免重复 $fileName = uniqid() . '.' . $ext; $savePath = $saveDir . $fileName; // 按格式输出 switch ($mime) { case 'image/jpeg': imagejpeg($resized, $savePath, 90); // 90是画质参数 break; case 'image/png': imagepng($resized, $savePath, 6); // 6是压缩比 break; case 'image/webp': imagewebp($resized, $savePath, 90); break; } // 释放内存 imagedestroy($original); imagedestroy($resized); // 后续可以直接用$savePath存数据库等操作 $promolink = $savePath; }
内容的提问来源于stack exchange,提问作者arkitektron
相关产品推荐
相关产品推荐

