广告位联系
返回顶部

PHP中图像处理的利器GD库的操作流程

php 来源:互联网 作者:佚名 发布时间:2026-10-02 10:54:32 人浏览
摘要

在 PHP 开发中,GD 库是处理图像的核心利器:生成验证码、制作缩略图、添加水印、绘制简单图表 这些高频需求都能通过 GD 库轻松实现。 开启需修改php.ini,取消extension=gd(Windows)或extension

在 PHP 开发中,GD 库是处理图像的核心利器:生成验证码、制作缩略图、添加水印、绘制简单图表…… 这些高频需求都能通过 GD 库轻松实现。

开启需修改 php.ini,取消 extension=gd(Windows)或 extension=gd.so(Linux)前的注释,重启 Web 服务即可。

GD 库基本操作流程

所有 GD 操作都遵循 “创建画布 → 分配颜色 → 绘制内容 → 输出 / 保存 → 销毁资源” 的流程:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?php

// 1. 创建画布(宽 400,高 200)

$image = imagecreatetruecolor(400, 200);

 

// 2. 分配颜色(RGB 值)

$white = imagecolorallocate($image, 255, 255, 255); // 白色

$black = imagecolorallocate($image, 0, 0, 0);       // 黑色

 

// 3. 填充背景色

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

 

// 4. 绘制内容(比如写一行字)

imagestring($image, 5, 100, 90, 'Hello GD!', $black);

 

// 5. 输出图像(或保存到文件)

header('Content-Type: image/png'); // 告诉浏览器输出的是 PNG 图片

imagepng($image);

 

// 6. 销毁资源,释放内存

imagedestroy($image);

?>

常用功能

绘制基本图形

GD 库支持绘制直线、矩形、圆形、椭圆等基础图形,适合制作简单图表或标记。

函数 说明
imageline() 绘制直线
imagerectangle() 绘制矩形(边框)
imagefilledrectangle() 绘制填充矩形
imageellipse() 绘制椭圆(圆形是椭圆的特例)
imagefilledellipse() 绘制填充椭圆

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

// 创建画布

$image = imagecreatetruecolor(400, 300);

$white = imagecolorallocate($image, 255, 255, 255);

$red = imagecolorallocate($image, 255, 0, 0);

$blue = imagecolorallocate($image, 0, 0, 255);

$green = imagecolorallocate($image, 0, 255, 0);

 

// 填充白色背景

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

 

// 1. 绘制红色直线(从 x1,y1 到 x2,y2)

imageline($image, 50, 50, 350, 50, $red);

 

// 2. 绘制蓝色矩形边框(x1,y1 左上角,x2,y2 右下角)

imagerectangle($image, 50, 80, 150, 180, $blue);

 

// 3. 绘制绿色填充矩形

imagefilledrectangle($image, 200, 80, 350, 180, $green);

 

// 4. 绘制红色填充圆形(圆心 x,y,宽高相同即为圆)

imagefilledellipse($image, 200, 240, 80, 80, $red);

 

// 输出图像

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

imagepng($image);

imagedestroy($image);

生成缩略图

网站上传图片时,生成缩略图是刚需。GD 库通过 imagecopyresampled() 实现高质量缩放。

  • imagecreatefromjpeg() / imagecreatefrompng():从现有图片创建画布资源。
  • imagecopyresampled():重采样复制图像(比 imagecopyresized() 更清晰,推荐使用)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

/**

 * 生成等比例缩略图

 * @param string $srcPath 原图路径

 * @param string $destPath 缩略图保存路径

 * @param int $maxWidth 最大宽度

 * @param int $maxHeight 最大高度

 */

function createThumbnail($srcPath, $destPath, $maxWidth = 200, $maxHeight = 200) {

    // 获取原图信息

    list($srcWidth, $srcHeight, $type) = getimagesize($srcPath);

     

    // 根据图片类型创建画布

    switch ($type) {

        case IMAGETYPE_JPEG:

            $srcImage = imagecreatefromjpeg($srcPath);

            break;

        case IMAGETYPE_PNG:

            $srcImage = imagecreatefrompng($srcPath);

            break;

        default:

            return false;

    }

     

    // 计算等比例缩放后的尺寸

    $scale = min($maxWidth / $srcWidth, $maxHeight / $srcHeight);

    $destWidth = $srcWidth * $scale;

    $destHeight = $srcHeight * $scale;

     

    // 创建缩略图画布

    $destImage = imagecreatetruecolor($destWidth, $destHeight);

     

    // 处理 PNG 透明背景(可选,若不需要可省略)

    if ($type == IMAGETYPE_PNG) {

        $transparent = imagecolorallocatealpha($destImage, 255, 255, 255, 127);

        imagefill($destImage, 0, 0, $transparent);

        imagesavealpha($destImage, true);

    }

     

    // 重采样复制(核心步骤)

    imagecopyresampled(

        $destImage, $srcImage, // 目标画布、源画布

        0, 0, 0, 0,            // 目标 x,y、源 x,y

        $destWidth, $destHeight,// 目标宽高

        $srcWidth, $srcHeight   // 源宽高

    );

     

    // 保存缩略图

    switch ($type) {

        case IMAGETYPE_JPEG:

            imagejpeg($destImage, $destPath, 90); // 90 是 JPEG 质量

            break;

        case IMAGETYPE_PNG:

            imagepng($destImage, $destPath);

            break;

    }

     

    // 销毁资源

    imagedestroy($srcImage);

    imagedestroy($destImage);

    return true;

}

添加水印

文字水印

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

/**

 * 添加文字水印

 * @param string $srcPath 原图路径

 * @param string $text 水印文字

 * @param string $fontPath 字体文件路径(需支持中文,比如 simhei.ttf)

 */

function addTextWatermark($srcPath, $text, $fontPath = './simhei.ttf') {

    // 获取原图信息

    list($width, $height, $type) = getimagesize($srcPath);

    switch ($type) {

        case IMAGETYPE_JPEG:

            $image = imagecreatefromjpeg($srcPath);

            break;

        case IMAGETYPE_PNG:

            $image = imagecreatefrompng($srcPath);

            break;

        default:

            return false;

    }

     

    // 分配水印颜色(半透明白色)

    $watermarkColor = imagecolorallocatealpha($image, 255, 255, 255, 50); // 50 是透明度(0-127,越大越透明)

     

    // 设置字体大小

    $fontSize = 20;

     

    // 计算文字位置(右下角)

    $bbox = imagettfbbox($fontSize, 0, $fontPath, $text);

    $textWidth = $bbox[2] - $bbox[0];

    $textHeight = $bbox[1] - $bbox[7];

    $x = $width - $textWidth - 20; // 距离右边 20px

    $y = $height - $textHeight - 20; // 距离下边 20px

     

    // 写入文字(使用 TrueType 字体,支持中文)

    imagettftext($image, $fontSize, 0, $x, $y, $watermarkColor, $fontPath, $text);

     

    // 保存图片

    $destPath = './watermark_text.jpg';

    switch ($type) {

        case IMAGETYPE_JPEG:

            imagejpeg($image, $destPath, 90);

            break;

        case IMAGETYPE_PNG:

            imagepng($image, $destPath);

            break;

    }

     

    imagedestroy($image);

    return $destPath;

}

图片水印

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

/**

 * 添加图片水印

 * @param string $srcPath 原图路径

 * @param string $watermarkPath 水印图片路径(建议 PNG 透明图)

 */

function addImageWatermark($srcPath, $watermarkPath) {

    // 获取原图和水印图信息

    list($srcWidth, $srcHeight, $srcType) = getimagesize($srcPath);

    list($wmWidth, $wmHeight, $wmType) = getimagesize($watermarkPath);

     

    // 创建画布

    switch ($srcType) {

        case IMAGETYPE_JPEG:

            $srcImage = imagecreatefromjpeg($srcPath);

            break;

        case IMAGETYPE_PNG:

            $srcImage = imagecreatefrompng($srcPath);

            break;

        default:

            return false;

    }

    $wmImage = imagecreatefrompng($watermarkPath); // 假设水印是 PNG

     

    // 计算水印位置(右下角)

    $x = $srcWidth - $wmWidth - 20;

    $y = $srcHeight - $wmHeight - 20;

     

    // 合并水印(保留 PNG 透明度)

    imagecopy($srcImage, $wmImage, $x, $y, 0, 0, $wmWidth, $wmHeight);

     

    // 保存图片

    $destPath = './watermark_image.jpg';

    switch ($srcType) {

        case IMAGETYPE_JPEG:

            imagejpeg($srcImage, $destPath, 90);

            break;

        case IMAGETYPE_PNG:

            imagepng($srcImage, $destPath);

            break;

    }

     

    imagedestroy($srcImage);

    imagedestroy($wmImage);

    return $destPath;

}

生成验证码

验证码是防止恶意注册、刷接口的常用手段,GD 库生成验证码的核心是 “随机字符 + 干扰线 + 噪点”。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

<?php

session_start(); // 开启 Session,用于保存验证码

 

// 1. 创建画布

$width = 120;

$height = 40;

$image = imagecreatetruecolor($width, $height);

 

// 2. 分配颜色

$white = imagecolorallocate($image, 255, 255, 255);

$gray = imagecolorallocate($image, 200, 200, 200);

$darkGray = imagecolorallocate($image, 100, 100, 100);

 

// 3. 填充背景

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

 

// 4. 绘制干扰线(3 条)

for ($i = 0; $i < 3; $i++) {

    $lineColor = imagecolorallocate($image, rand(100, 200), rand(100, 200), rand(100, 200));

    imageline($image, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $lineColor);

}

 

// 5. 绘制噪点(50 个)

for ($i = 0; $i < 50; $i++) {

    $dotColor = imagecolorallocate($image, rand(50, 150), rand(50, 150), rand(50, 150));

    imagesetpixel($image, rand(0, $width), rand(0, $height), $dotColor);

}

 

// 6. 生成随机验证码

$chars = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'; // 去掉易混淆的 0、1、O、l

$code = '';

for ($i = 0; $i < 4; $i++) {

    $code .= $chars[rand(0, strlen($chars) - 1)];

}

 

// 保存到 Session,用于后续验证

$_SESSION['captcha'] = strtolower($code);

 

// 7. 写入验证码文字

$fontSize = 16;

$fontPath = './simhei.ttf'; // 可选,若没有可用 imagestring

for ($i = 0; $i < 4; $i++) {

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

    $x = 15 + $i * 25;

    $y = rand(25, 35);

    imagettftext($image, $fontSize, rand(-10, 10), $x, $y, $charColor, $fontPath, $code[$i]);

}

 

// 8. 输出图像

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

imagepng($image);

imagedestroy($image);

?>

注意事项

  • 记得销毁资源:每次 GD 操作后,务必用 imagedestroy() 销毁图像资源,避免内存泄漏。
  • 输出前无任何输出:在 header('Content-Type: image/png') 前,不能有任何 HTML 标签、空格或换行,否则会导致图像无法显示。
  • 处理大图片注意内存:处理高分辨率图片时,可能会超出 PHP 内存限制,可在代码开头临时调整:ini_set('memory_limit', '256M');。
  • 中文支持用 TrueType 字体:imagestring() 不支持中文,需用 imagettftext() 配合 .ttf 字体文件(如 simhei.ttf 黑体)。
  • 优先使用 imagecopyresampled() :缩放图片时,imagecopyresampled() 会进行重采样,生成的缩略图更清晰,不要用 imagecopyresized()。

版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • PHP中图像处理的利器GD库的操作流程
    在 PHP 开发中,GD 库是处理图像的核心利器:生成验证码、制作缩略图、添加水印、绘制简单图表 这些高频需求都能通过 GD 库轻松实现。
  • 使用PHP将Word文件转换为PDF文件的三种方式

    使用PHP将Word文件转换为PDF文件的三种方式
    环境准备: 服务器:CentOS 7.8 PHP:7.2 一、 使用 PHPWord + Dompdf(纯 PHP,无需系统软件,推荐轻量场景) 或使用mpdf或者tcpdf都可以,原理就是
  • phpenv搭建PHP多版本管理工具
    phpenv是一个简单易用的PHP版本管理工具,帮助开发者轻松管理多个PHP版本并实现快速切换。如果你需要在同一台机器上测试不同版本的PHP应
  • phpenv安装和配置指南
    1. 项目基础介绍和主要编程语言 项目介绍 phpenv 是一个用于简化管理多个 PHP 版本的开源项目。它允许开发者在同一台机器上安装和管理多个
  • PHP二维数组按某字段排序怎么写
    用usort()配合匿名函数是最直接的写法 PHP 没有内置的「按字段名排序二维数组」函数,usort()是最常用也最可控的方式。它允许你自定义比较
  • 如何正确处理 PHP 后端脚本的错误响应(以 Tele
    本文详解如何在 ajax 表单提交中准确捕获并响应php后端(如 telegram bot api 调用)的真实错误状态,避免 `fopen()` 静默失败问题,通过 curl +
  • PHP调用Workerman5.0实现一对一聊天
    要实现一对一聊天功能,使用 Workerman 5.0 作为后端,前端可以使用 WebSocket 进行通信。以下是实现步骤和代码示例。 1. 安装 Workerman 首先,确
  • PHP跨文件传递参数的8种常见方法
    以下是 PHP 中跨文件传递参数的8 种常见方法,按场景和安全性分类整理,附详细说明和示例代码: 一、超全局变量(适合请求间数据共享)
  • PHP+HTML实现流式输出效果的示例

    PHP+HTML实现流式输出效果的示例
    效果演示 后端代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 ?php // 关闭输出缓冲 ini_set(output_bu
  • 在PHP中使用__dir__的详细介绍
    __DIR__ 可以用来获取当前代码工作目录。它从PHP 5.3版本开始引入。它类似于使用 dirname(__FILE__)。通常用于包含其他文件,这些文件存在于一
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计