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

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=67108864
  • memory_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 02:21:00