news 2026/6/4 7:35:00

PHP图像处理与GD库实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP图像处理与GD库实战

PHP图像处理与GD库实战

PHP的GD库提供了图像处理功能。虽然不如图形处理专业软件强大,但处理常见的图片需求绰绰有余。

GD库可以创建图片、处理已有图片、添加文字水印、生成缩略图等。先检查GD库是否安装。

```php
// 检查GD库
if (!extension_loaded('gd')) {
die("GD库未安装\n");
}

echo "GD版本: " . gd_info()['GD Version'] . "\n";
echo "支持的格式:\n";
$formats = ['GIF', 'JPEG', 'PNG', 'WEBP', 'BMP'];
foreach ($formats as $format) {
$func = "image" . strtolower($format);
echo " $format: " . (function_exists($func) ? '支持' : '不支持') . "\n";
}
?>
```

创建缩略图是GD库最常用的功能:

```php
function createThumbnail(string $source, string $dest, int $maxWidth = 300, int $maxHeight = 300): bool
{
if (!file_exists($source)) {
throw new RuntimeException("源文件不存在: $source");
}

$info = getimagesize($source);
if ($info === false) {
throw new RuntimeException("无法获取图片信息");
}

[$origWidth, $origHeight, $type] = $info;

// 计算缩放比例
$ratio = min($maxWidth / $origWidth, $maxHeight / $origHeight);
$newWidth = (int)($origWidth * $ratio);
$newHeight = (int)($origHeight * $ratio);

// 创建源图像
$sourceImage = match ($type) {
IMAGETYPE_JPEG => imagecreatefromjpeg($source),
IMAGETYPE_PNG => imagecreatefrompng($source),
IMAGETYPE_GIF => imagecreatefromgif($source),
IMAGETYPE_WEBP => imagecreatefromwebp($source),
default => throw new RuntimeException("不支持的图片类型: $type"),
};

// 创建目标图像
$thumb = imagecreatetruecolor($newWidth, $newHeight);

// 保持PNG透明
if ($type === IMAGETYPE_PNG) {
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
}

// 重采样
imagecopyresampled($thumb, $sourceImage, 0, 0, 0, 0,
$newWidth, $newHeight, $origWidth, $origHeight);

// 保存
$result = match ($type) {
IMAGETYPE_JPEG => imagejpeg($thumb, $dest, 85),
IMAGETYPE_PNG => imagepng($thumb, $dest, 9),
IMAGETYPE_GIF => imagegif($thumb, $dest),
IMAGETYPE_WEBP => imagewebp($thumb, $dest, 85),
};

imagedestroy($sourceImage);
imagedestroy($thumb);

return $result;
}

// 生成示例图片
$width = 800;
$height = 600;
$image = imagecreatetruecolor($width, $height);

// 填充背景
$bgColor = imagecolorallocate($image, 240, 240, 240);
imagefill($image, 0, 0, $bgColor);

// 画一些图形
$red = imagecolorallocate($image, 255, 0, 0);
$green = imagecolorallocate($image, 0, 255, 0);
$blue = imagecolorallocate($image, 0, 0, 255);

imagefilledrectangle($image, 50, 50, 200, 200, $red);
imagefilledellipse($image, 400, 200, 150, 150, $green);
imagefilledrectangle($image, 600, 100, 750, 250, $blue);

imagejpeg($image, '/tmp/test.jpg', 85);
imagedestroy($image);

// 生成缩略图
createThumbnail('/tmp/test.jpg', '/tmp/thumb.jpg', 200, 200);
echo "缩略图已创建\n";
?>
```

给图片添加水印:

```php
function addWatermark(string $sourcePath, string $destPath, string $watermarkText): bool
{
$image = imagecreatefromjpeg($sourcePath);
if ($image === false) {
throw new RuntimeException("无法打开图片");
}

$width = imagesx($image);
$height = imagesy($image);

// 白色半透明文字
$fontSize = 20;
$textColor = imagecolorallocatealpha($image, 255, 255, 255, 60);

// 使用内置字体
$fontX = $width - 200;
$fontY = $height - 30;

imagestring($image, 5, $fontX, $fontY, $watermarkText, $textColor);

$result = imagejpeg($image, $destPath, 90);
imagedestroy($image);

return $result;
}

// 图片裁剪
function cropImage(string $sourcePath, string $destPath, int $x, int $y, int $width, int $height): bool
{
$image = imagecreatefromjpeg($sourcePath);
if ($image === false) {
throw new RuntimeException("无法打开图片");
}

$cropped = imagecrop($image, ['x' => $x, 'y' => $y, 'width' => $width, 'height' => $height]);

if ($cropped === false) {
imagedestroy($image);
throw new RuntimeException("裁剪失败");
}

$result = imagejpeg($cropped, $destPath, 90);
imagedestroy($cropped);
imagedestroy($image);

return $result;
}
?>
```

用GD库生成验证码图片:

```php
function generateCaptcha(int $width = 150, int $height = 50, int $length = 4): string
{
$image = imagecreatetruecolor($width, $height);

// 背景色
$bgColor = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $bgColor);

// 干扰线
for ($i = 0; $i < 5; $i++) {
$lineColor = imagecolorallocate($image,
rand(150, 200), rand(150, 200), rand(150, 200));
imageline($image,
rand(0, $width), rand(0, $height),
rand(0, $width), rand(0, $height),
$lineColor);
}

// 干扰点
for ($i = 0; $i < 100; $i++) {
$pointColor = imagecolorallocate($image,
rand(100, 200), rand(100, 200), rand(100, 200));
imagesetpixel($image, rand(0, $width), rand(0, $height), $pointColor);
}

// 验证码文字
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$code = '';
$fontSize = 20;

for ($i = 0; $i < $length; $i++) {
$char = $chars[rand(0, strlen($chars) - 1)];
$code .= $char;

$textColor = imagecolorallocate($image,
rand(0, 100), rand(0, 100), rand(0, 100));

$x = 20 + $i * 30 + rand(-5, 5);
$y = 20 + rand(-5, 5);

imagestring($image, 5, $x, $y, $char, $textColor);
}

header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);

return $code;
}

// 如果直接访问这个脚本,生成验证码
if (isset($_GET['captcha'])) {
$code = generateCaptcha();
session_start();
$_SESSION['captcha'] = $code;
exit;
}
?>
```

用GD库生成简单的图表:

```php
function createBarChart(array $data, string $destPath, int $width = 600, int $height = 400): void
{
$image = imagecreatetruecolor($width, $height);

$white = imagecolorallocate($image, 255, 255, 255);
$black = imagecolorallocate($image, 0, 0, 0);
$colors = [
imagecolorallocate($image, 52, 152, 219),
imagecolorallocate($image, 46, 204, 113),
imagecolorallocate($image, 231, 76, 60),
imagecolorallocate($image, 241, 196, 15),
imagecolorallocate($image, 155, 89, 182),
];

imagefill($image, 0, 0, $white);

$padding = 50;
$chartWidth = $width - 2 * $padding;
$chartHeight = $height - 2 * $padding;

// 坐标轴
imageline($image, $padding, $padding, $padding, $height - $padding, $black);
imageline($image, $padding, $height - $padding, $width - $padding, $height - $padding, $black);

$maxValue = max($data);
$barCount = count($data);
$barWidth = ($chartWidth / $barCount) - 10;

for ($i = 0; $i < $barCount; $i++) {
$barHeight = ($data[$i] / $maxValue) * $chartHeight;
$x = $padding + $i * ($barWidth + 10) + 5;
$y = $height - $padding - $barHeight;

$color = $colors[$i % count($colors)];
imagefilledrectangle($image, $x, $y, $x + $barWidth, $height - $padding, $color);

// 数值标签
$labelX = $x + ($barWidth - 20) / 2;
imagestring($image, 3, $x + 5, $y - 18, (string)$data[$i], $black);
}

imagepng($image, $destPath);
imagedestroy($image);
}

$data = [85, 92, 78, 95, 88];
createBarChart($data, '/tmp/chart.png');
echo "图表已生成: /tmp/chart.png\n";
?>
```

GD库的功能很丰富,但也有一些限制。处理大图片时内存占用很高,建议先检查可用内存再操作。生成图片的质量可以通过调整压缩参数来控制,JPEG是0-100,PNG是0-9。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 7:33:06

GLM-5开源代码模型如何重构程序员工作流

1. 项目概述&#xff1a;当一个开源大模型开始“写代码像人”&#xff0c;程序员的日常就变了“智谱GLM-5这次开源&#xff0c;让高级程序员也危险了……”——这句话在技术圈刷屏那天&#xff0c;我正蹲在客户现场调一个遗留系统的Java线程池死锁。手机弹出消息&#xff0c;没…

作者头像 李华
网站建设 2026/6/4 7:29:00

从收藏吃灰到高效执行:2026年度高内聚代码灵感仓储工具深度解析

很多独立开发者和科研团队都遇到过类似的尴尬&#xff1a;在 GitHub 上看到极其惊艳的开源项目或算法架构&#xff0c;随手点了 Star&#xff0c;可几个月后自己要用时&#xff0c;却怎么也找不到&#xff1b;或者在参与数学建模、科创比赛、编写毕业设计时&#xff0c;收集了一…

作者头像 李华
网站建设 2026/6/4 7:25:14

基于Arduino Uno自制赛车模拟器:从电位器到游戏控制器的完整指南

1. 项目概述与核心思路一直想给自己攒一套赛车模拟器&#xff0c;但市面上的成品要么价格劝退&#xff0c;要么功能固定缺乏折腾的乐趣。作为一个电子爱好者&#xff0c;我始终相信&#xff0c;最趁手的工具往往是自己做出来的。这次的项目&#xff0c;就是用一块几乎人手一块的…

作者头像 李华
网站建设 2026/6/4 7:23:35

避开DH参数坑:6轴机械臂运动学建模与正逆解计算的3个常见误区

6轴机械臂运动学建模实战&#xff1a;避开DH参数与正逆解计算的三大陷阱机械臂运动学建模就像搭建一座精密的桥梁——参数设定稍有偏差&#xff0c;整个系统就会崩塌。Gluon-6L3这类6轴机械臂的DH参数配置中&#xff0c;关节坐标系对齐偏差导致的位姿误差可能累积放大到末端执行…

作者头像 李华
网站建设 2026/6/4 7:17:54

Bokeh:Python 交互式可视化的老牌选择

文章目录Bokeh&#xff1a;Python 交互式可视化的老牌选择1、Bokeh 是干什么的2、为什么要用它3、核心能力4、安装使用5、适合哪些人用Bokeh&#xff1a;Python 交互式可视化的老牌选择 bokeh 在 GitHub 上已经拿到 20.3K Star 了。 做数据可视化的 Python 开发者基本都听说过…

作者头像 李华