PHPAPI水印怎么添加

wen PHP项目 5

本文目录导读:

PHPAPI水印怎么添加

  1. 方法一:使用GD库(最常用)
  2. 方法二:使用Imagick(功能更强大)
  3. 方法三:添加文字水印(GD库)
  4. 注意事项

在PHP中给图片添加水印,主要使用 GD库Imagick 扩展,下面我给出两种方式的完整代码示例。

使用GD库(最常用)

<?php
/**
 * 给图片添加水印
 * @param string $source 原图路径
 * @param string $watermark 水印图片路径(推荐PNG格式,支持透明)
 * @param string $output 输出路径
 * @param int $position 位置:1-9,对应九宫格位置
 * @param int $padding 边距(像素)
 */
function addWatermark($source, $watermark, $output = '', $position = 9, $padding = 20) {
    // 获取原图信息
    $sourceInfo = getimagesize($source);
    $sourceWidth = $sourceInfo[0];
    $sourceHeight = $sourceInfo[1];
    $sourceType = $sourceInfo[2];
    // 根据图片类型创建原图资源
    switch ($sourceType) {
        case IMAGETYPE_JPEG:
            $sourceImage = imagecreatefromjpeg($source);
            break;
        case IMAGETYPE_PNG:
            $sourceImage = imagecreatefrompng($source);
            break;
        case IMAGETYPE_GIF:
            $sourceImage = imagecreatefromgif($source);
            break;
        default:
            return false;
    }
    // 获取水印图片信息并创建水印资源
    $watermarkInfo = getimagesize($watermark);
    $waterWidth = $watermarkInfo[0];
    $waterHeight = $watermarkInfo[1];
    $waterImage = imagecreatefrompng($watermark);
    // 计算水印位置(九宫格定位)
    $positionMap = [
        1 => ['x' => $padding, 'y' => $padding], // 左上
        2 => ['x' => ($sourceWidth - $waterWidth) / 2, 'y' => $padding], // 上中
        3 => ['x' => $sourceWidth - $waterWidth - $padding, 'y' => $padding], // 右上
        4 => ['x' => $padding, 'y' => ($sourceHeight - $waterHeight) / 2], // 左中
        5 => ['x' => ($sourceWidth - $waterWidth) / 2, 'y' => ($sourceHeight - $waterHeight) / 2], // 居中
        6 => ['x' => $sourceWidth - $waterWidth - $padding, 'y' => ($sourceHeight - $waterHeight) / 2], // 右中
        7 => ['x' => $padding, 'y' => $sourceHeight - $waterHeight - $padding], // 左下
        8 => ['x' => ($sourceWidth - $waterWidth) / 2, 'y' => $sourceHeight - $waterHeight - $padding], // 下中
        9 => ['x' => $sourceWidth - $waterWidth - $padding, 'y' => $sourceHeight - $waterHeight - $padding], // 右下
    ];
    $pos = $positionMap[$position] ?? $positionMap[9];
    // 合并图片(支持透明通道)
    imagealphablending($sourceImage, true);
    imagesavealpha($sourceImage, true);
    imagecopy($sourceImage, $waterImage, $pos['x'], $pos['y'], 0, 0, $waterWidth, $waterHeight);
    // 输出/保存
    if (empty($output)) {
        $output = $source; // 覆盖原图
    }
    switch ($sourceType) {
        case IMAGETYPE_JPEG:
            imagejpeg($sourceImage, $output, 100);
            break;
        case IMAGETYPE_PNG:
            imagepng($sourceImage, $output, 0);
            break;
        case IMAGETYPE_GIF:
            imagegif($sourceImage, $output);
            break;
    }
    // 释放内存
    imagedestroy($sourceImage);
    imagedestroy($waterImage);
    return true;
}
// 使用示例
addWatermark('source.jpg', 'watermark.png', 'output.jpg', 9, 20);
?>

使用Imagick(功能更强大)

<?php
/**
 * 使用Imagick添加水印
 */
function addWatermarkImagick($source, $watermark, $output = '', $position = 'southeast', $padding = 20) {
    try {
        $image = new Imagick($source);
        $water = new Imagick($watermark);
        // 获取尺寸
        $imageWidth = $image->getImageWidth();
        $imageHeight = $image->getImageHeight();
        $waterWidth = $water->getImageWidth();
        $waterHeight = $water->getImageHeight();
        // 计算位置
        switch ($position) {
            case 'northwest': // 左上
                $x = $padding;
                $y = $padding;
                break;
            case 'north': // 上中
                $x = ($imageWidth - $waterWidth) / 2;
                $y = $padding;
                break;
            case 'northeast': // 右上
                $x = $imageWidth - $waterWidth - $padding;
                $y = $padding;
                break;
            case 'west': // 左中
                $x = $padding;
                $y = ($imageHeight - $waterHeight) / 2;
                break;
            case 'center': // 居中
                $x = ($imageWidth - $waterWidth) / 2;
                $y = ($imageHeight - $waterHeight) / 2;
                break;
            case 'east': // 右中
                $x = $imageWidth - $waterWidth - $padding;
                $y = ($imageHeight - $waterHeight) / 2;
                break;
            case 'southwest': // 左下
                $x = $padding;
                $y = $imageHeight - $waterHeight - $padding;
                break;
            case 'south': // 下中
                $x = ($imageWidth - $waterWidth) / 2;
                $y = $imageHeight - $waterHeight - $padding;
                break;
            case 'southeast': // 右下(默认)
            default:
                $x = $imageWidth - $waterWidth - $padding;
                $y = $imageHeight - $waterHeight - $padding;
                break;
        }
        // 合并水印
        $image->compositeImage($water, Imagick::COMPOSITE_OVER, $x, $y);
        // 输出
        if (empty($output)) {
            $output = $source;
        }
        $image->writeImage($output);
        // 释放
        $image->clear();
        $water->clear();
        return true;
    } catch (Exception $e) {
        return false;
    }
}
// 使用示例
addWatermarkImagick('source.jpg', 'watermark.png', 'output.jpg', 'southeast', 20);
?>

添加文字水印(GD库)

<?php
/**
 * 添加文字水印
 */
function addTextWatermark($source, $text, $output = '', $fontSize = 20, $position = 9) {
    // 获取原图信息
    $sourceInfo = getimagesize($source);
    $sourceWidth = $sourceInfo[0];
    $sourceHeight = $sourceInfo[1];
    $sourceType = $sourceInfo[2];
    // 创建图像资源
    switch ($sourceType) {
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg($source);
            break;
        case IMAGETYPE_PNG:
            $image = imagecreatefrompng($source);
            break;
        case IMAGETYPE_GIF:
            $image = imagecreatefromgif($source);
            break;
        default:
            return false;
    }
    // 设置文字颜色(白色,半透明)
    $textColor = imagecolorallocatealpha($image, 255, 255, 255, 50);
    // 中文字体路径(需要下载中文字体文件)
    $fontFile = 'path/to/your/font.ttf'; // simsun.ttc 或 msyh.ttf
    // 获取文字边界
    $bbox = imagettfbbox($fontSize, 0, $fontFile, $text);
    $textWidth = $bbox[2] - $bbox[0];
    $textHeight = $bbox[1] - $bbox[7];
    // 计算位置
    $padding = 20;
    $positions = [
        1 => ['x' => $padding, 'y' => $textHeight + $padding],
        2 => ['x' => ($sourceWidth - $textWidth) / 2, 'y' => $textHeight + $padding],
        3 => ['x' => $sourceWidth - $textWidth - $padding, 'y' => $textHeight + $padding],
        4 => ['x' => $padding, 'y' => ($sourceHeight - $textHeight) / 2],
        5 => ['x' => ($sourceWidth - $textWidth) / 2, 'y' => ($sourceHeight - $textHeight) / 2],
        6 => ['x' => $sourceWidth - $textWidth - $padding, 'y' => ($sourceHeight - $textHeight) / 2],
        7 => ['x' => $padding, 'y' => $sourceHeight - $padding],
        8 => ['x' => ($sourceWidth - $textWidth) / 2, 'y' => $sourceHeight - $padding],
        9 => ['x' => $sourceWidth - $textWidth - $padding, 'y' => $sourceHeight - $padding],
    ];
    $pos = $positions[$position] ?? $positions[9];
    // 写入文字
    imagettftext($image, $fontSize, 0, $pos['x'], $pos['y'], $textColor, $fontFile, $text);
    // 输出
    if (empty($output)) {
        $output = $source;
    }
    switch ($sourceType) {
        case IMAGETYPE_JPEG:
            imagejpeg($image, $output, 100);
            break;
        case IMAGETYPE_PNG:
            imagepng($image, $output, 0);
            break;
        case IMAGETYPE_GIF:
            imagegif($image, $output);
            break;
    }
    imagedestroy($image);
    return true;
}
// 使用示例
addTextWatermark('source.jpg', '© 2024 My Website', 'output.jpg', 24, 9);
?>

注意事项

  1. GD库检查:使用前确认已启用GD库:

    if (extension_loaded('gd')) {
        echo "GD库已启用";
    }
  2. 水印图片格式:推荐使用PNG格式,支持透明通道

  3. 字体文件:文字水印需要指定中文字体文件路径

  4. 性能优化:大量图片处理时建议使用队列或异步处理

  5. 权限问题:确保图片目录有写入权限

选择哪种方法取决于你的具体需求和服务器环境配置,GD库几乎都有,Imagick功能更强但需要额外安装。

抱歉,评论功能暂时关闭!