插件窝 干货文章 nginx如何通过PHP代理给图片加水印

nginx如何通过PHP代理给图片加水印

IMAGE 水印 PHP watermark 623    来源:    2025-04-21

使用Nginx和PHP为图片添加水印

要通过Nginx和PHP代理方式为图片添加水印,可以采用以下方案:

方案一:Nginx + PHP-FPM 代理处理

  1. Nginx配置
location ~* ^/watermark/(.*)\.(jpg|jpeg|png|gif)$ {
    try_files $uri @watermark;
}

location @watermark {
    # 将请求转发给PHP处理
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # 根据实际情况修改PHP版本
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/watermark.php;
    fastcgi_param IMAGE_PATH $1.$2;
}
  1. PHP处理脚本 (watermark.php)
<?php
// 获取原始图片路径
$imagePath = $_SERVER['DOCUMENT_ROOT'] . '/' . $_SERVER['IMAGE_PATH'];

// 检查图片是否存在
if (!file_exists($imagePath)) {
    header("HTTP/1.0 404 Not Found");
    exit;
}

// 获取图片类型
$mimeType = mime_content_type($imagePath);
header("Content-Type: $mimeType");

// 创建图像资源
switch ($mimeType) {
    case 'image/jpeg':
        $image = imagecreatefromjpeg($imagePath);
        break;
    case 'image/png':
        $image = imagecreatefrompng($imagePath);
        break;
    case 'image/gif':
        $image = imagecreatefromgif($imagePath);
        break;
    default:
        header("HTTP/1.0 400 Bad Request");
        exit;
}

// 设置水印文本
$watermarkText = "Copyright";
$font = '/path/to/font.ttf'; // 水印字体文件路径
$fontSize = 20;
$color = imagecolorallocatealpha($image, 255, 255, 255, 60); // 半透明白色

// 计算水印位置(右下角)
$textBox = imagettfbbox($fontSize, 0, $font, $watermarkText);
$textWidth = $textBox[2] - $textBox[0];
$textHeight = $textBox[7] - $textBox[1];
$margin = 10;
$x = imagesx($image) - $textWidth - $margin;
$y = imagesy($image) - $textHeight - $margin;

// 添加水印
imagettftext($image, $fontSize, 0, $x, $y, $color, $font, $watermarkText);

// 输出图像
switch ($mimeType) {
    case 'image/jpeg':
        imagejpeg($image);
        break;
    case 'image/png':
        imagepng($image);
        break;
    case 'image/gif':
        imagegif($image);
        break;
}

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

方案二:使用Nginx的X-Accel-Redirect (更高效)

  1. Nginx配置
location ~* ^/images/(.*)\.(jpg|jpeg|png|gif)$ {
    try_files $uri @watermark;
}

location @watermark {
    # 内部重定向到PHP处理
    rewrite ^/images/(.*)$ /watermark.php?image=$1 last;
}

location = /watermark.php {
    internal; # 只允许内部访问
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/watermark.php;
}
  1. PHP处理脚本 (watermark.php)
<?php
$imagePath = $_SERVER['DOCUMENT_ROOT'] . '/images/' . $_GET['image'];

// ... (与方案一相同的图像处理代码)

// 使用X-Accel-Redirect返回处理后的图像
header("X-Accel-Redirect: /protected_images/" . basename($imagePath));
?>

优化建议

  1. 缓存处理:添加缓存头或使用Nginx缓存已处理图像
  2. 性能优化:对于高流量站点,考虑使用OpenResty + Lua实现
  3. 安全考虑:验证输入路径,防止目录遍历攻击
  4. 水印多样化:可以支持图片水印而不仅是文字水印

扩展功能

如果需要更复杂的水印处理,可以考虑使用以下PHP库: - Intervention Image (https://image.intervention.io/) - Imagine (https://imagine.readthedocs.io/) - GD或Imagick扩展

以上方案可以根据实际需求进行调整,方案二在性能上更优,适合高并发场景。