当前位置: 首页 > 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.jsqmd.com/news/947345/

相关文章:

  • 道路积水数据集 路面积水识别数据集 图片数量4524,xml和txt标签都有;公路积水数据集 ✓类别:puddle;
  • CAPL数据处理避坑指南:当byte数组遇上Hex字符串,这些细节你注意了吗?
  • Spartan-6 FPGA上跑通AD9238双路12位25MHz实时采集的完整ISE工程包
  • C#抽象类 接口(简答 + 答题话术)
  • 性价比最高的仓储软件(WMS)怎么选 - 品牌排行榜
  • 第九章:Token 优化与高效省钱配置(重点)
  • 3分钟快速部署智慧树自动刷课插件:彻底解放双手的终极学习助手
  • 2026年|迎战5月查重死线!10款全网最火降AI工具亲测,零成本高效降AI率指南 - 降AI实验室
  • 气缸驱动并联机器人位姿控制策略【附仿真】
  • Vue版Cesium卫星轨道+雷达扫描三维可视化组件(含CZML数据与小程序适配)
  • 2026年6月可靠的工业皮带生产厂家推荐,输送带/工业皮带/pvc输送带/食品输送带,工业皮带源头厂家有哪些 - 品牌推荐师
  • 联想AI主机Mini: 优质AI订阅替代方案实测
  • PHP图像识别与QR码生成技术
  • 语义内核形式化模型:AI内容生成的统一数学原理与工程实践
  • Grok-1本地部署构建自动素材池实战指南
  • 仓储软件(WMS)值得推荐的实用选择参考 - 品牌排行榜
  • 从安装到调参:一份超详细的imbalanced-learn库实战指南(附Jupyter Notebook代码)
  • 深耕车载数字健康场景,守护全维度驾乘安全与体验
  • 小程序毕业设计-基于ssm电影院网上订票系统的设计与实现小程序基于Android的电影院网上订票系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • GBase 8s数据库高可用之—RHAC远程高可用集群详解
  • PHP图形验证码技术实现
  • 从收藏吃灰到高效执行:2026年度高内聚代码灵感仓储工具深度解析
  • 第七章:自定义命令、规则与上下文
  • 别慌!网站突然打不开显示Error 522?手把手教你排查百度云加速与源站的连接问题
  • DeepSeek V4实测:百万上下文与MoE架构如何重构AI成本模型
  • 量子退火在最小顶点多割问题中的应用与优化
  • 仓储软件(WMS)值得推荐的选择方向 - 品牌排行榜
  • 第八章:工具、权限与 MCP 扩展
  • 用超声波传感器与Arduino制作自由形态电子秤:从测距到称重的跨界实践
  • 如何快速定位手机号码归属地:三步完成精准查询