PHP文生图返回空白,95%是Content-Type头未设或设错且GD资源创建失败:必须用header('Content-Type: image/png')匹配imagepng(),检查imagecreatetruecolor()等返回值是否为false,清除BOM及前置输出,并调用imagedestroy()释放内存。

PHP文生图返回空白,95% 是 header 没设对或设晚了——不是 GD 没画出来,而是浏览器根本没把它当图片看。
Content-Type 必须匹配 imagepng() / imagejpeg() 实际输出格式
GD 函数名和 header 的 MIME 类型必须严格一致,否则浏览器收到二进制却按 HTML 解析,结果就是白屏或乱码。
-
imagepng($im)前必须用header('Content-Type: image/png');写成image/jpg或image/peng都会失败 -
imagejpeg($im)对应header('Content-Type: image/jpeg');image/jpg是常见错误,MIME 标准里没有jpg这个类型 - WebP 支持需 PHP ≥ 7.1 且 GD 编译时启用了 libwebp,函数为
imagewebp(),header 必须是image/webp - 如果用
imagegif(),注意 GIF 动画不支持真彩色,imagecreatetruecolor()创建后要转调色板:imagepalettetotruecolor()或改用imagecreate()
输出前绝对不能有任何字符(含 BOM、空格、换行)
哪怕一个 UTF-8 BOM 字节(EF BB BF)在 <?php 前,都会触发 Warning: Cannot modify header information,后续 imagepng() 虽然执行了,但 header 已失效,浏览器收不到类型声明。
- 用 VS Code 或 Notepad++ 检查文件编码:必须存为「UTF-8 无 BOM」
- 确认
<?php是文件第一个字符,前面不能有空行、空格、注释或<?xml等任何内容 - include 的文件也得检查——哪怕
config.php结尾多了一个换行,也会导致 header 失败 - 临时调试可用
if (headers_sent($file, $line)) { die("headers sent at {$file}:{$line}"); }定位源头
动态图必须禁用缓存,否则改了代码也不刷新
浏览器对固定 URL(如 gen.php?w=200&h=100)极易缓存响应体,哪怕你每次重新生成图片,它仍从本地加载旧二进制。
立即学习“PHP免费学习笔记(深入)”;
- 加这三行强制禁用存储:
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');、header('Pragma: no-cache');、header('Expires: 0'); - 避免只写
no-cache——它允许协商缓存(ETag/Last-Modified),而no-store才真正禁止写入磁盘 - 别在代码里手动返回
HTTP/1.1 304 Not Modified,动态图没有“未修改”概念;若用了条件头逻辑,务必校验 ETag(比如基于参数和时间戳的 md5)再决定是否 304 - 开发期可临时在 URL 后加
&t=<?php echo time(); ?>绕过,但上线前必须靠 header 控制
GD 创建失败时不会报错,但 imagepng() 会静默失败
imagecreatetruecolor() 或 imagecolorallocate() 返回 false 时,后续 GD 操作全无效,imagepng() 却不会抛异常,只会输出空内容,页面看起来就是空白。
- 每一步都检查返回值:
$im = imagecreatetruecolor(600, 400); if (!$im) { die('imagecreatetruecolor failed'); } - 颜色分配也要判:
$bg = imagecolorallocate($im, 255, 255, 255); if ($bg === false) { die('imagecolorallocate failed'); } - 出错时调
error_get_last()查最后错误,常能看到Allowed memory size exhausted——GD 图像内存占用是宽×高×4 字节,2000×2000 就要 16MB - 记得最后调
imagedestroy($im),否则内存不释放,高频请求下可能直接 OOM
最易被忽略的是:header 设置时机和 GD 资源有效性必须同时成立。单点修复(比如只改 MIME 类型却不查 BOM,或只加 no-store 却忘了判断 imagecreatetruecolor() 是否返回 false)依然会返回空白。



















