PHP imagecopyresampled()仅支持JPG,处理PNG时返回500错误
问题描述
我用PHP编写API请求,需要将表单上传的图片缩放至1024×1024分辨率。当前脚本处理JPG文件正常,但处理PNG文件时返回500错误,即使将PNG重命名为.jpg也无法正常处理。
相关代码
$fileInfo = pathinfo($_FILES['image']['name']); $fileExtension = strtolower($fileInfo['extension']); $allowedExtensions = array( 'jpg', 'jpeg', 'png', 'gif', 'wbmp', 'webp' ); $allowedMimeTypes = array( 'image/jpeg', 'image/png', 'image/gif', 'image/wbmp', 'image/webp' ); // 检查文件扩展名和MIME类型 if (!in_array($fileExtension, $allowedExtensions) || !in_array($_FILES['image']['type'], $allowedMimeTypes)) { echo "错误:仅允许JPEG、PNG、GIF、WBMP和WEBP文件。"; exit; } // 检查文件大小 if ($_FILES['image']['size'] > 5 * 1024 * 1024) { echo "错误:文件大小不能超过5MB。"; exit; } $imageInfo = getimagesize($_FILES['image']['tmp_name']); $imageWidth = $imageInfo[0]; $imageHeight = $imageInfo[1]; $imagePixelCount = $imageWidth * $imageHeight; if ($imagePixelCount > 1048576) { // 1048576像素 echo "错误:图片像素不能超过1048576。"; exit; } // 测试邮件 $to = 'info@example.com'; $subject = 'Check1'; $message = 'C'; $headers = array('Content-Type: text/html; charset=UTF-8'); wp_mail($to, $subject, $message, $headers); switch ($_FILES['image']['type']) { case 'image/jpeg': case 'image/pjpeg': // 有时JPEG会显示为pjpeg $sourceImage = imagecreatefromjpeg($_FILES['image']['tmp_name']); break; case 'image/png': $sourceImage = imagecreatefrompng($_FILES['image']['tmp_name']); // 保留PNG透明度 imagealphablending($resizedImage, false); imagesavealpha($resizedImage, true); break; case 'image/gif': $sourceImage = imagecreatefromgif($_FILES['image']['tmp_name']); break; case 'image/webp': $sourceImage = imagecreatefromwebp($_FILES['image']['tmp_name']); break; case 'image/bmp': case 'image/x-windows-bmp': $sourceImage = imagecreatefrombmp($_FILES['image']['tmp_name']); break; // ... 其他支持的格式 ... default: echo "错误:未知图片格式。"; exit; } // 创建指定尺寸的目标图片 $newWidth = 1024; $newHeight = 1024; $resizedImage = imagecreatetruecolor($newWidth, $newHeight); // TODO 错误:仅对jpg文件有效 // 缩放图片 imagecopyresampled($resizedImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $imageWidth, $imageHeight); // 保存缩放后的图片 // $tempFilePath = $_FILES['image']['tmp_name'] . "_resized." . $fileExtension; $tempFilePath = $_FILES['image']['tmp_name'] . "_resized"; switch ($fileExtension) { case 'jpg': case 'jpeg': imagejpeg($resizedImage, $tempFilePath); break; case 'png': imagepng($resizedImage, $tempFilePath); break; case 'gif': imagegif($resizedImage, $tempFilePath); break; // ... 添加其他支持的格式 ... } // 清理资源 imagedestroy($sourceImage); imagedestroy($resizedImage);
PHP配置限制
upload_max_filesize=67108864memory_limit=805306368
错误日志
2024-03-11T17:59:44+00:00 CRITICAL Uncaught ValueError: Path cannot be empty in /.../kbe_engine/bildzubild_V.1.20.php:297 CONTEXT: {"error":{"type":1,"file":"\/homepages\/44\/d4297367306\/htdocs\/wordpress\/kbe_engine\/bildzubild_V.1.20.php","line":297},"backtrace":["","#0 \/homepages\/44\/d4297367306\/htdocs\/wordpress\/kbe_engine\/bildzubild_V.1.20.php(297): curl_setopt()","#1 {main}","thrown"]}
解决方案
1. 修复PNG透明度处理顺序错误
在处理PNG的switch分支中,你提前操作了$resizedImage变量,但这个变量要到后续才会通过imagecreatetruecolor创建,这会导致未定义变量错误,进而影响后续文件保存流程。
修改处理PNG的分支:
case 'image/png': $sourceImage = imagecreatefrompng($_FILES['image']['tmp_name']); break;
然后在创建$resizedImage之后添加透明度设置:
// 创建指定尺寸的目标图片 $newWidth = 1024; $newHeight = 1024; $resizedImage = imagecreatetruecolor($newWidth, $newHeight); // 针对PNG保留透明度 if ($_FILES['image']['type'] === 'image/png') { imagealphablending($resizedImage, false); imagesavealpha($resizedImage, true); }
2. 确保临时文件路径有效
当前$tempFilePath没有添加文件扩展名,虽然imagepng能写入文件,但后续curl请求可能无法识别该文件,导致路径为空错误。恢复带扩展名的路径:
$tempFilePath = $_FILES['image']['tmp_name'] . "_resized." . $fileExtension;
3. 检查curl请求的路径变量
错误日志显示第297行curl_setopt的路径为空,说明后续使用$tempFilePath时文件未成功生成。需确保:
- 图片保存目录有写入权限
$tempFilePath在curl调用前未被清空或覆盖
修正后的关键代码片段
// 处理源图片 switch ($_FILES['image']['type']) { case 'image/jpeg': case 'image/pjpeg': $sourceImage = imagecreatefromjpeg($_FILES['image']['tmp_name']); break; case 'image/png': $sourceImage = imagecreatefrompng($_FILES['image']['tmp_name']); break; case 'image/gif': $sourceImage = imagecreatefromgif($_FILES['image']['tmp_name']); break; case 'image/webp': $sourceImage = imagecreatefromwebp($_FILES['image']['tmp_name']); break; case 'image/bmp': case 'image/x-windows-bmp': $sourceImage = imagecreatefrombmp($_FILES['image']['tmp_name']); break; default: echo "错误:未知图片格式。"; exit; } // 创建目标图片并设置PNG透明度 $newWidth = 1024; $newHeight = 1024; $resizedImage = imagecreatetruecolor($newWidth, $newHeight); if ($_FILES['image']['type'] === 'image/png') { imagealphablending($resizedImage, false); imagesavealpha($resizedImage, true); } // 缩放图片 imagecopyresampled($resizedImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $imageWidth, $imageHeight); // 保存缩放后的图片(带扩展名) $tempFilePath = $_FILES['image']['tmp_name'] . "_resized." . $fileExtension; switch ($fileExtension) { case 'jpg': case 'jpeg': imagejpeg($resizedImage, $tempFilePath); break; case 'png': imagepng($resizedImage, $tempFilePath); break; case 'gif': imagegif($resizedImage, $tempFilePath); break; } // 清理资源 imagedestroy($sourceImage); imagedestroy($resizedImage);
内容的提问来源于stack exchange,提问作者user23581031
相关产品推荐
相关产品推荐

