PHP GD库生成缩略图完整示例
本文介绍如何利用PHP内置的GD扩展库,在用户上传图片时自动计算尺寸并生成等比缩略图。核心步骤包括接收上传文件、验证合法性、获取原图尺寸、按比例计算目标宽高以及使用图像重采样函数输出新图片。
实现思路与流程
生成缩略图的核心在于保持图片比例不变形。我们需要先读取上传文件的实际分辨率(宽和高),然后设定一个最大限制值(例如300像素)。根据原图是横向还是纵向,决定哪个维度优先满足该限制,另一个维度则按比例缩小。最后通过GD库的绘图功能创建画布并重绘图片。
准备工作
- 确保服务器已安装并启用
GD扩展。可以通过 phpinfo() 或php -m | grep gd进行检查。 - 在当前脚本运行目录下创建一个
upload文件夹,并确保Web用户对它有写入权限,否则保存缩略图时会报错。
第1步:构建上传表单
首先需要一个HTML表单来接收用户选择的图片。注意表单的 method 必须为 post,且 enctype 必须设置为 multipart/form-data,以便正确传输二进制文件数据。
<form method="post" action="suo_do.php" enctype="multipart/form-data">
<input type="file" name="pic" /
>
<input type="submit" value="上传" /
>
</form>
第2步:处理上传与安全检查
在 suo_do.php 中,首先配置时区和字符集。接着对上传的文件进行基础校验:
- 检查
$_FILES数组是否为空,防止直接访问脚本。 - 检查
$_FILES['pic']['error'],非零值表示上传过程出现错误。 - 验证文件后缀是否在允许列表中(如 jpg, png, jpeg, gif),防止非法文件执行。
以下代码片段展示了这些检查逻辑及临时文件的移动:
<?php
header("content-type:text/html;charset=gbk");
ini_set("date.timezone","Asia/Shanghai"); // 修正时区写法
// 1. 判断文件是否为空
if(empty($_FILES)){
echo "未检测到上传文件";
exit;
}
// 2. 判断文件上传是否有错误
if($_FILES['pic']['error']){
echo "上传文件出错,错误代码: " . $_FILES['pic']['error'];
exit;
}
// 3. 判断文件类型是否合法
$allowtype=array("jpg","png","jpeg","gif");
$a=explode('.',$_FILES['pic']['name']);
$index=count($a)-1;
$ex=strtolower($a[$index]);
if(!in_array($ex,$allowtype)){
echo "上传文件格式不支持";
exit;
}
// 4. 移动临时文件到指定目录
$file=date('YmdHis').rand().".".$ex;
$src=$_FILES['pic']['tmp_name'];
$des="upload/".$file;
$rs=move_uploaded_file($src,$des);
if(!$rs){
echo "文件保存失败";
exit;
}
?>
第3步:获取原图尺寸并计算缩略图大小
使用 getimagesize() 函数可以获取图片的宽度 ($a[0]) 和高度 ($a[1])。为了实现等比缩放,我们设定一个基准尺寸(例如300px):
- 如果原图宽大于高(横向图),让宽度等于300,高度按原比例缩小。
- 如果原图宽小于高(纵向图),让高度等于300,宽度按原比例缩小。
- 如果宽高相等,则两者均为300。
// 读取已经上传图片的尺寸
$image=imagecreatefromjpeg($des); // 注意:若支持PNG/GIF需切换对应函数
$a=getimagesize($des);
$w=$a[0];
$h=$a[1];
// 设定最大边长为300
if($w > $h){
$width=300;
$height=floor($width/$w*$h); // 使用floor避免浮点数导致的问题
} else if($w < $h){
$height=300;
$width=floor($height/$h*$w);
} else{
$width=300;
$height=300;
}
注意:上面的代码仅使用了 imagecreatefromjpeg。在实际应用中,应使用 imagecreatefromstring(file_get_contents($des)) 或者根据 $ex 后缀动态调用 imagecreatefrompng、imagecreatefromgif 以支持所有允许的类型。
第4步:创建新画布并重绘图片
使用 imagecreatetruecolor() 创建一个指定宽高的真彩色空白画布。然后使用 imagecopyresized() 将原图的内容复制到新画布上。虽然 imagecopyresampled() 画质更好,但 imagecopyresized 性能更快,适合简单的缩略图生成场景。
// 创建空白新图片画布
$newimage=imagecreatetruecolor($width, $height);
// copy源图片内容到新图片
imagecopyresized($newimage, $image, 0, 0, 0, 0, $width, $height, $w, $h);
// 保存缩略图
$filename="upload/s_".$file;
imagejpeg($newimage,$filename, 85); // 第二个参数为质量(0-100)
// 释放内存
imagedestroy($image);
imagedestroy($newimage);
完成判断
当代码成功运行后,检查服务器上的 upload 目录:
- 会存在一个原始文件,文件名由时间戳+随机数构成。
- 会存在一个缩略图文件,文件名以
s_开头。 - 缩略图的长边应为300像素左右,且视觉比例与原图一致。
排错提示
- Warning: getimagesize()...:通常是因为文件路径错误或文件损坏。确认
upload目录存在且可写。 - Call to undefined function imagecreatefromjpeg():服务器上未安装GD库。联系管理员开启扩展。
- 中文文件名乱码:部分旧版PHP或操作系统在处理含中文的临时文件名时可能出现编码问题。建议始终使用英文命名规则(如本例中的时间戳组合)。
简要总结
本示例展示了基于PHP GD库的最基础缩略图生成流程。关键点在于通过 getimagesize 获取维度信息,应用数学比例计算新尺寸,并利用 imagecopyresized 完成像素复制。对于生产环境,建议增加对图片类型的严格判定(而非仅依赖后缀),并考虑使用 imagecopyresampled 以提升缩略图清晰度。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













