Skip to content

图片处理(GD 库)

PHP 的 GD 库是常用的图片处理扩展,本文介绍常见的图片操作。

基础操作

php
// 创建画布
$image = imagecreatetruecolor(400, 300);

// 分配颜色
$white = imagecolorallocate($image, 255, 255, 255);
$red = imagecolorallocate($image, 255, 0, 0);

// 填充背景
imagefill($image, 0, 0, $white);

// 绘制图形
imageline($image, 0, 0, 400, 300, $red);  // 画线
imagerectangle($image, 50, 50, 150, 150, $red);  // 画矩形
imageellipse($image, 200, 150, 100, 80, $red);  // 画椭圆

// 添加文字
$text = "Hello GD";
imagestring($image, 5, 150, 140, $text, $red);

// 输出图片
header('Content-Type: image/png');
imagepng($image);

// 释放内存
imagedestroy($image);

读取和处理现有图片

php
// 从文件创建图片
$src = imagecreatefromjpeg('photo.jpg');
// imagecreatefrompng('photo.png')
// imagecreatefromgif('photo.gif')

// 获取图片尺寸
$width = imagesx($src);
$height = imagesy($src);

// 等比例缩放
$newWidth = 200;
$newHeight = ($height / $width) * $newWidth;

$dst = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

// 保存图片
imagejpeg($dst, 'thumbnail.jpg', 90);  // 90% 质量

imagedestroy($src);
imagedestroy($dst);

添加水印

php
function addWatermark($source, $watermark, $output, $position = 'bottom-right') {
    // 加载原图和水印
    $srcImg = imagecreatefromjpeg($source);
    $waterImg = imagecreatefrompng($watermark);

    $srcW = imagesx($srcImg);
    $srcH = imagesy($srcImg);
    $waterW = imagesx($waterImg);
    $waterH = imagesy($waterImg);

    // 计算位置
    $padding = 10;
    switch ($position) {
        case 'top-left':
            $x = $padding;
            $y = $padding;
            break;
        case 'top-right':
            $x = $srcW - $waterW - $padding;
            $y = $padding;
            break;
        case 'bottom-left':
            $x = $padding;
            $y = $srcH - $waterH - $padding;
            break;
        case 'center':
            $x = ($srcW - $waterW) / 2;
            $y = ($srcH - $waterH) / 2;
            break;
        case 'bottom-right':
        default:
            $x = $srcW - $waterW - $padding;
            $y = $srcH - $waterH - $padding;
    }

    // 合并图片(保持 PNG 透明度)
    imagecopy($srcImg, $waterImg, $x, $y, 0, 0, $waterW, $waterH);

    // 保存
    imagejpeg($srcImg, $output, 95);

    imagedestroy($srcImg);
    imagedestroy($waterImg);
}

// 文字水印
function addTextWatermark($source, $text, $output) {
    $image = imagecreatefromjpeg($source);
    $color = imagecolorallocatealpha($image, 255, 255, 255, 50);  // 半透明白

    $font = 5;  // 内置字体
    $x = 10;
    $y = imagesy($image) - 20;

    imagestring($image, $font, $x, $y, $text, $color);
    imagejpeg($image, $output);
    imagedestroy($image);
}

创建验证码图片

php
function createCaptcha($length = 4) {
    $width = 120;
    $height = 40;

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

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

    // 生成随机字符
    $chars = '23456789abcdefghjkmnpqrstuvwxyz';
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= $chars[mt_rand(0, strlen($chars) - 1)];
    }

    // 添加干扰线
    for ($i = 0; $i < 5; $i++) {
        $color = imagecolorallocate($image, mt_rand(0, 150), mt_rand(0, 150), mt_rand(0, 150));
        imageline($image, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0, $width), mt_rand(0, $height), $color);
    }

    // 绘制文字
    for ($i = 0; $i < $length; $i++) {
        $color = imagecolorallocate($image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
        $x = 15 + $i * 25;
        $y = mt_rand(20, 30);
        imagestring($image, 5, $x, $y, $code[$i], $color);
    }

    // 添加干扰点
    for ($i = 0; $i < 50; $i++) {
        $color = imagecolorallocate($image, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
        imagesetpixel($image, mt_rand(0, $width), mt_rand(0, $height), $color);
    }

    // 存储验证码到 session
    session_start();
    $_SESSION['captcha'] = strtolower($code);

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

注意事项

  1. 处理大图片时注意内存限制
  2. 使用 imagecreatetruecolor() 支持真彩色
  3. PNG 图片需要保留透明度时,使用 imagealphablending()imagesavealpha()
  4. 记得调用 imagedestroy() 释放内存

Binstork