本文目录导读:

我来详细介绍使用PHP的GD库和Imagick扩展动态生成图像水印的方法。
使用GD库生成水印
图片水印
<?php
/**
* 使用GD库添加图片水印
* @param string $sourcePath 原图路径
* @param string $watermarkPath 水印图片路径
* @param string $outputPath 输出路径
* @param int $position 水印位置(1-9,类似九宫格)
* @param int $opacity 透明度(0-100)
*/
function addWatermarkWithGD($sourcePath, $watermarkPath, $outputPath, $position = 9, $opacity = 50) {
// 获取原图信息
$sourceInfo = getimagesize($sourcePath);
$sourceWidth = $sourceInfo[0];
$sourceHeight = $sourceInfo[1];
$sourceMime = $sourceInfo['mime'];
// 创建原图资源
switch ($sourceMime) {
case 'image/jpeg':
$sourceImg = imagecreatefromjpeg($sourcePath);
break;
case 'image/png':
$sourceImg = imagecreatefrompng($sourcePath);
break;
case 'image/gif':
$sourceImg = imagecreatefromgif($sourcePath);
break;
default:
return false;
}
// 获取水印图片信息
$watermarkInfo = getimagesize($watermarkPath);
$watermarkWidth = $watermarkInfo[0];
$watermarkHeight = $watermarkInfo[1];
// 创建水印图片资源
$watermarkImg = imagecreatefrompng($watermarkPath);
// 设置水印位置(边距20像素)
$margin = 20;
switch ($position) {
case 1: // 左上
$destX = $margin;
$destY = $margin;
break;
case 2: // 中上
$destX = ($sourceWidth - $watermarkWidth) / 2;
$destY = $margin;
break;
case 3: // 右上
$destX = $sourceWidth - $watermarkWidth - $margin;
$destY = $margin;
break;
case 4: // 左中
$destX = $margin;
$destY = ($sourceHeight - $watermarkHeight) / 2;
break;
case 5: // 居中
$destX = ($sourceWidth - $watermarkWidth) / 2;
$destY = ($sourceHeight - $watermarkHeight) / 2;
break;
case 6: // 右中
$destX = $sourceWidth - $watermarkWidth - $margin;
$destY = ($sourceHeight - $watermarkHeight) / 2;
break;
case 7: // 左下
$destX = $margin;
$destY = $sourceHeight - $watermarkHeight - $margin;
break;
case 8: // 中下
$destX = ($sourceWidth - $watermarkWidth) / 2;
$destY = $sourceHeight - $watermarkHeight - $margin;
break;
case 9: // 右下
$destX = $sourceWidth - $watermarkWidth - $margin;
$destY = $sourceHeight - $watermarkHeight - $margin;
break;
default:
$destX = $sourceWidth - $watermarkWidth - $margin;
$destY = $sourceHeight - $watermarkHeight - $margin;
}
// 应用透明度并合并图片
imagecopymerge($sourceImg, $watermarkImg, $destX, $destY, 0, 0,
$watermarkWidth, $watermarkHeight, $opacity);
// 保存图片
switch ($sourceMime) {
case 'image/jpeg':
imagejpeg($sourceImg, $outputPath, 90);
break;
case 'image/png':
imagepng($sourceImg, $outputPath, 9);
break;
case 'image/gif':
imagegif($sourceImg, $outputPath);
break;
}
// 释放内存
imagedestroy($sourceImg);
imagedestroy($watermarkImg);
return true;
}
// 使用示例
addWatermarkWithGD('source.jpg', 'watermark.png', 'output.jpg', 9, 50);
文字水印
<?php
/**
* 使用GD库添加文字水印
* @param string $sourcePath 原图路径
* @param string $outputPath 输出路径
* @param string $text 水印文字
* @param array $options 配置选项
*/
function addTextWatermarkWithGD($sourcePath, $outputPath, $text, $options = []) {
// 默认配置
$defaultOptions = [
'fontSize' => 20,
'fontColor' => [255, 255, 255],
'fontFile' => './arial.ttf', // 需要字体文件
'position' => 9,
'opacity' => 50,
'angle' => 0
];
$options = array_merge($defaultOptions, $options);
// 获取原图信息
$sourceInfo = getimagesize($sourcePath);
$sourceWidth = $sourceInfo[0];
$sourceHeight = $sourceInfo[1];
$sourceMime = $sourceInfo['mime'];
// 创建原图资源
switch ($sourceMime) {
case 'image/jpeg':
$sourceImg = imagecreatefromjpeg($sourcePath);
break;
case 'image/png':
$sourceImg = imagecreatefrompng($sourcePath);
break;
case 'image/gif':
$sourceImg = imagecreatefromgif($sourcePath);
break;
default:
return false;
}
// 计算文字尺寸
$bbox = imagettfbbox($options['fontSize'], $options['angle'],
$options['fontFile'], $text);
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
// 设置位置
$margin = 20;
switch ($options['position']) {
case 1: // 左上
$x = $margin;
$y = $margin + $textHeight;
break;
case 3: // 右上
$x = $sourceWidth - $textWidth - $margin;
$y = $margin + $textHeight;
break;
case 5: // 居中
$x = ($sourceWidth - $textWidth) / 2;
$y = ($sourceHeight + $textHeight) / 2;
break;
case 7: // 左下
$x = $margin;
$y = $sourceHeight - $margin;
break;
case 9: // 右下
$x = $sourceWidth - $textWidth - $margin;
$y = $sourceHeight - $margin;
break;
default:
$x = $sourceWidth - $textWidth - $margin;
$y = $sourceHeight - $margin;
}
// 创建文字颜色(带透明度)
$color = imagecolorallocatealpha($sourceImg,
$options['fontColor'][0],
$options['fontColor'][1],
$options['fontColor'][2],
(100 - $options['opacity']) / 100 * 127);
// 添加文字水印
imagettftext($sourceImg, $options['fontSize'], $options['angle'],
$x, $y, $color, $options['fontFile'], $text);
// 保存图片
switch ($sourceMime) {
case 'image/jpeg':
imagejpeg($sourceImg, $outputPath, 90);
break;
case 'image/png':
imagepng($sourceImg, $outputPath, 9);
break;
case 'image/gif':
imagegif($sourceImg, $outputPath);
break;
}
imagedestroy($sourceImg);
return true;
}
// 使用示例
addTextWatermarkWithGD('source.jpg', 'output.jpg', '© 2024 My Website', [
'fontSize' => 24,
'fontColor' => [255, 255, 255],
'fontFile' => './fonts/arial.ttf',
'position' => 9,
'opacity' => 70,
'angle' => 0
]);
使用Imagick扩展生成水印
图片水印
<?php
/**
* 使用Imagick添加图片水印
* @param string $sourcePath 原图路径
* @param string $watermarkPath 水印图片路径
* @param string $outputPath 输出路径
* @param int $position 水印位置
* @param int $opacity 透明度(0-100)
*/
function addWatermarkWithImagick($sourcePath, $watermarkPath, $outputPath,
$position = 9, $opacity = 50) {
try {
// 创建Imagick对象
$image = new Imagick($sourcePath);
$watermark = new Imagick($watermarkPath);
// 获取尺寸
$imageWidth = $image->getImageWidth();
$imageHeight = $image->getImageHeight();
$watermarkWidth = $watermark->getImageWidth();
$watermarkHeight = $watermark->getImageHeight();
// 设置透明度
$watermark->setImageOpacity($opacity / 100);
// 计算位置
$margin = 20;
switch ($position) {
case 1: // 左上
$x = $margin;
$y = $margin;
break;
case 3: // 右上
$x = $imageWidth - $watermarkWidth - $margin;
$y = $margin;
break;
case 5: // 居中
$x = ($imageWidth - $watermarkWidth) / 2;
$y = ($imageHeight - $watermarkHeight) / 2;
break;
case 7: // 左下
$x = $margin;
$y = $imageHeight - $watermarkHeight - $margin;
break;
case 9: // 右下
$x = $imageWidth - $watermarkWidth - $margin;
$y = $imageHeight - $watermarkHeight - $margin;
break;
default:
$x = $imageWidth - $watermarkWidth - $margin;
$y = $imageHeight - $watermarkHeight - $margin;
}
// 合并图片
$image->compositeImage($watermark, Imagick::COMPOSITE_OVER, $x, $y);
// 保存图片
$image->writeImage($outputPath);
// 清理内存
$image->clear();
$watermark->clear();
return true;
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
return false;
}
}
// 使用示例
addWatermarkWithImagick('source.jpg', 'watermark.png', 'output.jpg', 9, 50);
文字水印
<?php
/**
* 使用Imagick添加文字水印
* @param string $sourcePath 原图路径
* @param string $outputPath 输出路径
* @param string $text 水印文字
* @param array $options 配置选项
*/
function addTextWatermarkWithImagick($sourcePath, $outputPath, $text, $options = []) {
// 默认配置
$defaultOptions = [
'fontSize' => 24,
'fontColor' => 'white',
'backgroundColor' => 'transparent',
'fontFile' => './arial.ttf',
'position' => 9,
'opacity' => 50,
'angle' => 0,
'gravity' => Imagick::GRAVITY_SOUTHEAST
];
$options = array_merge($defaultOptions, $options);
try {
// 创建原图对象
$image = new Imagick($sourcePath);
// 创建文字水印对象
$draw = new ImagickDraw();
$draw->setFont($options['fontFile']);
$draw->setFontSize($options['fontSize']);
$draw->setFillColor(new ImagickPixel($options['fontColor']));
$draw->setTextAlignment(Imagick::ALIGN_CENTER);
// 获取文字尺寸
$metrics = $image->queryFontMetrics($draw, $text);
$textWidth = $metrics['textWidth'];
$textHeight = $metrics['textHeight'];
// 创建水印图层
$watermark = new Imagick();
$watermark->newImage($textWidth + 40, $textHeight + 40,
new ImagickPixel($options['backgroundColor']));
$watermark->setImageFormat('png');
// 设置透明度
$watermark->setImageOpacity($options['opacity'] / 100);
// 绘制文字
$watermark->annotateImage($draw, 20, $textHeight + 20,
$options['angle'], $text);
// 设置水印位置
$imageWidth = $image->getImageWidth();
$imageHeight = $image->getImageHeight();
$watermarkWidth = $watermark->getImageWidth();
$watermarkHeight = $watermark->getImageHeight();
$margin = 20;
switch ($options['position']) {
case 1: // 左上
$x = $margin;
$y = $margin;
break;
case 3: // 右上
$x = $imageWidth - $watermarkWidth - $margin;
$y = $margin;
break;
case 5: // 居中
$x = ($imageWidth - $watermarkWidth) / 2;
$y = ($imageHeight - $watermarkHeight) / 2;
break;
case 7: // 左下
$x = $margin;
$y = $imageHeight - $watermarkHeight - $margin;
break;
case 9: // 右下
$x = $imageWidth - $watermarkWidth - $margin;
$y = $imageHeight - $watermarkHeight - $margin;
break;
default:
$x = $imageWidth - $watermarkWidth - $margin;
$y = $imageHeight - $watermarkHeight - $margin;
}
// 合并图片
$image->compositeImage($watermark, Imagick::COMPOSITE_OVER, $x, $y);
// 保存图片
$image->writeImage($outputPath);
// 清理内存
$image->clear();
$watermark->clear();
return true;
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
return false;
}
}
// 使用示例
addTextWatermarkWithImagick('source.jpg', 'output.jpg', '© 2024 My Website', [
'fontSize' => 30,
'fontColor' => 'white',
'fontFile' => './fonts/arial.ttf',
'position' => 9,
'opacity' => 60,
'angle' => -30 // 旋转角度
]);
批量处理水印
<?php
/**
* 批量添加水印
* @param string $directory 图片目录
* @param string $watermarkPath 水印路径
* @param string $outputDirectory 输出目录
* @param string $method 方法(gd或imagick)
*/
function batchAddWatermark($directory, $watermarkPath, $outputDirectory, $method = 'gd') {
// 确保输出目录存在
if (!file_exists($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
// 获取所有图片文件
$files = glob($directory . '/*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($files as $file) {
$filename = basename($file);
$outputPath = $outputDirectory . '/' . $filename;
if ($method == 'gd') {
addWatermarkWithGD($file, $watermarkPath, $outputPath, 9, 50);
} else {
addWatermarkWithImagick($file, $watermarkPath, $outputPath, 9, 50);
}
echo "Processed: $filename\n";
}
}
// 使用示例
batchAddWatermark('images/', 'watermark.png', 'watermarked_images/', 'gd');
性能对比与选择建议
GD库:
- 优点:PHP内置,无需额外安装
- 缺点:功能相对简单,处理大图片时性能较差
- 适用场景:简单水印需求,对性能要求不高
Imagick扩展:
- 优点:功能强大,支持更多图像格式,性能更好
- 缺点:需要安装扩展,资源消耗较大
- 适用场景:复杂水印需求,大批量处理
选择建议:如果只是简单的图片水印,使用GD库即可;如果有复杂的文字效果或需要处理高分辨率图片,建议使用Imagick。
注意事项
- 字体文件:使用文字水印时需要确保字体文件路径正确
- 权限问题:确保目录有写入权限
- 内存限制:处理大图片时可能需要调整PHP内存限制
- 错误处理:添加适当的错误处理和日志记录
- 缓存机制:对于频繁访问的图片,建议添加缓存机制
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播