当前位置: 首页 > news >正文

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。

http://www.rkmt.cn/news/1458859.html

相关文章:

  • CAPL数据处理避坑指南:当byte数组遇上Hex字符串,这些细节你注意了吗?
  • 2026年6月可靠的工业皮带生产厂家推荐,输送带/工业皮带/pvc输送带/食品输送带,工业皮带源头厂家有哪些 - 品牌推荐师
  • 2026年|迎战5月查重死线!10款全网最火降AI工具亲测,零成本高效降AI率指南 - 降AI实验室
  • 3分钟快速部署智慧树自动刷课插件:彻底解放双手的终极学习助手
  • 联想AI主机Mini: 优质AI订阅替代方案实测
  • 小程序毕业设计-基于ssm电影院网上订票系统的设计与实现小程序基于Android的电影院网上订票系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • PHP图形验证码技术实现
  • 第八章:工具、权限与 MCP 扩展
  • AI工具链×秒杀核心链路深度耦合实践(阿里/拼多多/得物三巨头架构师联合复盘版)
  • 伺服驱动器方向反转排查与设置
  • 高端音频旋转电位器怎么选?ALPS RK14J11R000H VS TONEVEE TV14 参数PK
  • 告别选型内耗,大模型API 采购中转成为企业 AI 降本增效新支点
  • 手机信号满格却上不了网?一文搞懂LTE/5G的PLMN选网与漫游机制
  • Gemma-2本地部署实战:手机电脑跑通2B大模型全指南
  • 2026年留学生降AI指南:实测3款结构级优化工具,英文论文轻松过Turnitin检测 - 降AI实验室
  • ARKFCM algorithm
  • 2026年北京工伤律师推荐:5位专业实力派精选 - 本地品牌推荐
  • Gemma 4B本地部署实战:轻量大模型在Mac与树莓派上的高效运行
  • 0.005mm同轴度,圆樽底模轴的车削精度怎么保证
  • 百度网盘全速下载终极指南:告别限速,轻松获取真实下载链接
  • QMCFLAC2MP3终极指南:一键解锁QQ音乐格式限制
  • 手把手解析BQ4050的SMBus数据:如何从原始字节算出真实的电压、电流和电量百分比?
  • 列表List的语法
  • 第四章:配置体系详解与优先级
  • 深耕本土,精准赋能 —— 徐允雯以专业商事服务助力苏州创业生态建设
  • Qwen3.6-Plus深度适配嵌入式开发:国产编程模型实战指南
  • 告别盲调!用海德汉PWM21深度解析Endat信号:从位置值、报警到信号质量百分比
  • Dreamweaver CS6里的‘层’到底怎么用?手把手教你用AP Div搞定网页布局(附实战案例)
  • 蜘蛛池技术解析:原理、作用与作用点评——专业视角下的网站录入
  • ECU标定工程师避坑指南:用ASAP2 Studio更新A2L时,这3个细节决定成败