直接用GD或Imagick生成博客封面完全可行,但必须解决图像尺寸适配、字体绝对路径与中文渲染、抗锯齿及alpha通道处理三关,否则易出现文字模糊、字体报错或白边锯齿等问题。

直接用 GD 或 Imagick 生成博客封面,不依赖外部 API、不卡 CDN 加载、不手动 PS,是完全可行的——但前提是图像尺寸、字体路径、中文渲染这三关过了,否则生成的图不是文字糊成一片,就是报 imagettftext(): Could not find/open font。
字体文件必须绝对路径 + 中文支持验证
PHP 的 imagettftext() 对中文字体极其敏感:相对路径会失败;.ttf 文件若无完整汉字集(比如只含 ASCII),中文直接变方块;某些系统自带字体(如 /System/Library/Fonts/PingFang.ttc)在 Linux 下根本不可读。
- 用
realpath('fonts/NotoSansCJKsc-Regular.ttf')获取绝对路径,别信__DIR__ . '/fonts/xxx.ttf'在 CLI 和 Web 环境下可能指向不同位置 - 测试前先跑一段最小验证代码:
$im = imagecreatetruecolor(200, 100);<br>$black = imagecolorallocate($im, 0, 0, 0);<br>var_dump(imagettftext($im, 14, 0, 10, 30, $black, '/abs/path/to/NotoSansCJKsc-Regular.ttf', '测'));<br>imagedestroy($im);
输出非false才算真正可用 - 推荐固定用
NotoSansCJKsc或SourceHanSansSC,避免系统字体差异
封面尺寸必须匹配目标平台规范
微信公众号要求 900×500,小红书推荐 3:4(1080×1440),知乎 Banner 是 1500×500——硬塞进一个“通用尺寸”只会让标题被裁或留大片空白。
- 脚本里不要写死宽高,改用配置数组:
$sizes = ['wechat' => [900, 500], 'xhs' => [1080, 1440]]; - 文字位置需按比例计算,例如标题 Y 坐标 =
$height * 0.65,而不是写死320 - 如果用
Imagick,注意setImageFormat('jpg')后必须调用setImageCompressionQuality(95),否则默认压缩极差
背景图合成时 alpha 通道和抗锯齿要手动开
直接 imagecopy() 叠加半透明文字或 logo,大概率出现白边、锯齿、色阶断裂——因为 GD 默认关闭抗锯齿,且 PNG 背景若有 alpha,没启用混合模式就直接覆盖。
立即学习“PHP免费学习笔记(深入)”;
- 绘文字前必加:
imageantialias($im, true);和imagesavealpha($im, true); - 叠加 PNG Logo 用
imagecopymerge($dst, $logo, $x, $y, 0, 0, $w, $h, 100),别用imagecopyresampled(会丢透明度) - 如果背景是渐变,用
imagefilledrectangle()配合imagecolorallocatealpha()控制透明度,比加载 PNG 更可控
真正卡住人的从来不是“怎么画个矩形”,而是字体路径在 cron 定时任务里失效、微信封面在 iPhone 上显示偏右、或者某次更新后 imagettfbbox() 返回负值导致坐标错乱——这些细节不打日志、不真机测、不查 getimagesize() 返回值,光靠本地浏览器预览永远发现不了。



















