Imagick PHP扩展库详解:为图片添加文本水印
本文将介绍如何使用PHP的Imagick扩展库为图片添加文本水印。我们将探讨多种方法,包括简单的文本叠加、使用字体蒙版创建透明文本水印,以及更高级的文字平铺技术。
关键要点:
annotateImage()
方法将文本添加到图像中,即可实现文本水印。setFillColor()
更改字体颜色,setFontSize()
更改字体大小,setFont()
更改字体,setFillOpacity()
添加透明度,以及annotateImage()
定位和旋转文本。在之前的文章中,Timothy Boronczyk 介绍了如何使用Imagick和叠加图像创建水印。本文将展示如何使用纯文本实现类似效果。目前,PHP的Imagick API文档非常匮乏,但ImageMagick网站上有很多命令行示例,我们将以此为起点。将命令行代码转换为PHP代码只是找到执行相同功能的相应方法的问题。以下示例将使用一张随机帅哥的图片。
在图像上绘制文本
最简单的文本水印是直接在图像上叠加字符串。命令行示例如下:
convert image.png -font Arial -pointsize 20 \ -draw "gravity south \ fill black text 0,12 'Copyright' \ fill white text 1,11 'Copyright'" \ result.png
对应的PHP代码:
<?php // 创建对象 $image = new Imagick('image.png'); // 水印文本 $text = 'Copyright'; // 创建新的绘图面板 $draw = new ImagickDraw(); // 设置字体属性 $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('black'); // 将文本定位在图像的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在图像上绘制文本 $image->annotateImage($draw, 10, 12, 0, $text); // 稍微偏移位置,使用不同的颜色再次绘制文本 $draw->setFillColor('white'); $image->annotateImage($draw, 11, 11, 0, $text); // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
效果图:
这个例子非常简单,代码注释也很清晰。虽然有效,但文本与图像对比度太强,效果不够柔和。
使用字体蒙版创建透明文本
为了使水印文本效果更柔和,可以使用字体蒙版创建透明文本。命令行示例:
convert -size 300x50 xc:grey30 -font Arial -pointsize 20 \ -gravity center -draw "fill grey70 text 0,0 'Copyright'" \ fgnd.png convert -size 300x50 xc:black -font Arial -pointsize 20 -gravity center \ -draw "fill white text 1,1 'Copyright' \ text 0,0 'Copyright' \ fill black text -1,-1 'Copyright'" \ +matte mask.png composite -compose CopyOpacity mask.png fgnd.png stamp.png mogrify -trim +repage stamp.png composite -gravity south -geometry +0+10 stamp.png image.png \ result.png
PHP代码:
<?php // 创建对象 $image = new Imagick('image.png'); $watermark = new Imagick(); $mask = new Imagick(); $draw = new ImagickDraw(); // 定义尺寸 $width = $image->getImageWidth(); $height = $image->getImageHeight(); // 创建调色板 $watermark->newImage($width, $height, new ImagickPixel('grey30')); $mask->newImage($width, $height, new ImagickPixel('black')); // 水印文本 $text = 'Copyright'; // 设置字体属性 $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('grey70'); // 将文本定位在图像的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在水印调色板上绘制文本 $watermark->annotateImage($draw, 10, 12, 0, $text); // 在蒙版调色板上绘制文本 $draw->setFillColor('white'); $mask->annotateImage($draw, 11, 13, 0, $text); $mask->annotateImage($draw, 10, 12, 0, $text); $draw->setFillColor('black'); $mask->annotateImage($draw, 9, 11, 0, $text); // 这是蒙版生效的必要条件 $mask->setImageMatte(false); // 将蒙版应用于水印 $watermark->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0); // 将水印叠加到图像上 $image->compositeImage($watermark, Imagick::COMPOSITE_DISSOLVE, 0, 0); // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
效果图:
此示例创建了多个图像。第一个图像$watermark
是灰度图像,第二个图像$mask
使用纯黑色表示要透明的部分,白色表示要保留的部分。当通过组合图像应用蒙版时,由于抗锯齿效果而在$mask
中找到的任何灰色阴影都将是半透明的,从而产生更平滑的边缘。在命令行版本代码中,在叠加水印之前会裁剪透明图像的外部边缘,但似乎存在一个错误,阻止compositeImage()
方法保留setGravity()
定义的位置。这意味着如果裁剪边缘,水印将失去其右下角的位置,并重新定位到左上角。为了解决此问题,创建的调色板与源图像具有相同的尺寸,因此不会发生裁剪。
文本平铺
最后一个示例将文本平铺在整个图像上,这使得移除水印更加困难。命令行:
convert image.png -font Arial -pointsize 20 \ -draw "gravity south \ fill black text 0,12 'Copyright' \ fill white text 1,11 'Copyright'" \ result.png
PHP代码:
<?php // 创建对象 $image = new Imagick('image.png'); // 水印文本 $text = 'Copyright'; // 创建新的绘图面板 $draw = new ImagickDraw(); // 设置字体属性 $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('black'); // 将文本定位在图像的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在图像上绘制文本 $image->annotateImage($draw, 10, 12, 0, $text); // 稍微偏移位置,使用不同的颜色再次绘制文本 $draw->setFillColor('white'); $image->annotateImage($draw, 11, 11, 0, $text); // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
效果图:
注意,这里使用setFillOpacity()
设置透明度,而不是使用图像蒙版。
总结
对于我来说,PHP中的图像处理已经成为该语言最令人愉快的方面之一,我希望Imagick能够在未来的版本中捆绑在一起。如果您正在寻找贡献方式,我鼓励您将其他命令行示例转换为PHP,然后将您的结果发布到官方PHP手册上,以便其他人学习和享受。
(图片来自Fotolia)
(以下为FAQ,已根据原文调整格式及内容,并进行伪原创)
关于使用Imagick在PHP中添加文本水印的常见问题 (FAQ)
问:如何使用PHP中的Imagick向图像添加文本水印?
答:使用PHP中的Imagick向图像添加文本水印,首先需要创建一个Imagick类的实例,并将图像读取到其中。然后,创建一个ImagickDraw实例并设置字体属性。之后,可以使用annotateImage()方法将文本添加到图像中。最后,使用writeImage()方法将图像写入文件系统。以下是一个基本示例:
convert -size 300x50 xc:grey30 -font Arial -pointsize 20 \ -gravity center -draw "fill grey70 text 0,0 'Copyright'" \ fgnd.png convert -size 300x50 xc:black -font Arial -pointsize 20 -gravity center \ -draw "fill white text 1,1 'Copyright' \ text 0,0 'Copyright' \ fill black text -1,-1 'Copyright'" \ +matte mask.png composite -compose CopyOpacity mask.png fgnd.png stamp.png mogrify -trim +repage stamp.png composite -gravity south -geometry +0+10 stamp.png image.png \ result.png
问:如何更改Imagick中水印文本的字体颜色?
答:可以使用ImagickDraw类的setFillColor()方法更改Imagick中水印文本的字体颜色。此方法接受表示颜色的字符串。例如,要将字体颜色设置为红色,可以执行以下操作:
<?php // 创建对象 $image = new Imagick('image.png'); $watermark = new Imagick(); $mask = new Imagick(); $draw = new ImagickDraw(); // 定义尺寸 $width = $image->getImageWidth(); $height = $image->getImageHeight(); // 创建调色板 $watermark->newImage($width, $height, new ImagickPixel('grey30')); $mask->newImage($width, $height, new ImagickPixel('black')); // 水印文本 $text = 'Copyright'; // 设置字体属性 $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('grey70'); // 将文本定位在图像的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在水印调色板上绘制文本 $watermark->annotateImage($draw, 10, 12, 0, $text); // 在蒙版调色板上绘制文本 $draw->setFillColor('white'); $mask->annotateImage($draw, 11, 13, 0, $text); $mask->annotateImage($draw, 10, 12, 0, $text); $draw->setFillColor('black'); $mask->annotateImage($draw, 9, 11, 0, $text); // 这是蒙版生效的必要条件 $mask->setImageMatte(false); // 将蒙版应用于水印 $watermark->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0); // 将水印叠加到图像上 $image->compositeImage($watermark, Imagick::COMPOSITE_DISSOLVE, 0, 0); // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
问:如何更改Imagick中水印文本的字体大小?
答:可以使用ImagickDraw类的setFontSize()方法更改Imagick中水印文本的字体大小。此方法接受表示字体大小的整数。例如,要将字体大小设置为30,可以执行以下操作:
convert image.png -font Arial -pointsize 20 \ -draw "gravity south \ fill black text 0,12 'Copyright' \ fill white text 1,11 'Copyright'" \ result.png
问:如何更改Imagick中水印文本的字体?
答:可以使用ImagickDraw类的setFont()方法更改Imagick中水印文本的字体。此方法接受表示字体名称的字符串。例如,要将字体设置为“Arial”,可以执行以下操作:
<?php // 创建对象 $image = new Imagick('image.png'); // 水印文本 $text = 'Copyright'; // 创建新的绘图面板 $draw = new ImagickDraw(); // 设置字体属性 $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('black'); // 将文本定位在图像的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在图像上绘制文本 $image->annotateImage($draw, 10, 12, 0, $text); // 稍微偏移位置,使用不同的颜色再次绘制文本 $draw->setFillColor('white'); $image->annotateImage($draw, 11, 11, 0, $text); // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
问:如何定位Imagick中的水印文本?
答:可以使用Imagick类的annotateImage()方法设置Imagick中水印文本的位置。此方法接受四个参数:ImagickDraw实例、文本的x和y坐标、文本的旋转角度和文本字符串。例如,要将文本定位在坐标(10, 45),可以执行以下操作:
convert -size 300x50 xc:grey30 -font Arial -pointsize 20 \ -gravity center -draw "fill grey70 text 0,0 'Copyright'" \ fgnd.png convert -size 300x50 xc:black -font Arial -pointsize 20 -gravity center \ -draw "fill white text 1,1 'Copyright' \ text 0,0 'Copyright' \ fill black text -1,-1 'Copyright'" \ +matte mask.png composite -compose CopyOpacity mask.png fgnd.png stamp.png mogrify -trim +repage stamp.png composite -gravity south -geometry +0+10 stamp.png image.png \ result.png
问:如何旋转Imagick中的水印文本?
答:可以使用Imagick类的annotateImage()方法设置Imagick中水印文本的旋转角度。此方法的第四个参数是文本的旋转角度。例如,要将文本旋转45度,可以执行以下操作:
<?php // 创建对象 $image = new Imagick('image.png'); $watermark = new Imagick(); $mask = new Imagick(); $draw = new ImagickDraw(); // 定义尺寸 $width = $image->getImageWidth(); $height = $image->getImageHeight(); // 创建调色板 $watermark->newImage($width, $height, new ImagickPixel('grey30')); $mask->newImage($width, $height, new ImagickPixel('black')); // 水印文本 $text = 'Copyright'; // 设置字体属性 $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('grey70'); // 将文本定位在图像的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在水印调色板上绘制文本 $watermark->annotateImage($draw, 10, 12, 0, $text); // 在蒙版调色板上绘制文本 $draw->setFillColor('white'); $mask->annotateImage($draw, 11, 13, 0, $text); $mask->annotateImage($draw, 10, 12, 0, $text); $draw->setFillColor('black'); $mask->annotateImage($draw, 9, 11, 0, $text); // 这是蒙版生效的必要条件 $mask->setImageMatte(false); // 将蒙版应用于水印 $watermark->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0); // 将水印叠加到图像上 $image->compositeImage($watermark, Imagick::COMPOSITE_DISSOLVE, 0, 0); // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
问:如何保存Imagick中的带水印图像?
答:可以使用Imagick类的writeImage()方法保存带水印的图像。此方法接受表示文件路径的字符串。例如,要将图像保存为“watermarked_image.png”,可以执行以下操作:
convert -size 140x80 xc:none -fill grey \ -gravity NorthWest -draw "text 10,10 'Copyright'" \ -gravity SouthEast -draw "text 5,15 'Copyright'" \ miff:- | \ composite -tile - image.png result.png
问:如何添加透明水印文本到Imagick?
答:可以使用ImagickDraw类的setFillOpacity()方法添加透明水印文本到Imagick。此方法接受表示不透明度级别的浮点数。例如,要将不透明度设置为0.5,可以执行以下操作:
<?php // 创建对象 $image = new Imagick('image.png'); $watermark = new Imagick(); // 水印文本 $text = 'Copyright'; // 创建新的绘图面板 $draw = new ImagickDraw(); $watermark->newImage(140, 80, new ImagickPixel('none')); // 设置字体属性 $draw->setFont('Arial'); $draw->setFillColor('grey'); $draw->setFillOpacity(.5); // 将文本定位在水印的左上角 $draw->setGravity(Imagick::GRAVITY_NORTHWEST); // 在水印上绘制文本 $watermark->annotateImage($draw, 10, 10, 0, $text); // 将文本定位在水印的右下角 $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // 在水印上绘制文本 $watermark->annotateImage($draw, 5, 15, 0, $text); // 重复将水印叠加到图像上 for ($w = 0; $w < $image->getImageWidth(); $w += 140) { for ($h = 0; $h < $image->getImageHeight(); $h += 80) { $image->compositeImage($watermark, Imagick::COMPOSITE_OVER, $w, $h); } } // 设置输出图像格式 $image->setImageFormat('png'); // 输出新图像 header('Content-type: image/png'); echo $image; ?>
问:如何在Imagick中为水印文本添加阴影?
答:可以通过绘制两次文本(一次用于阴影,一次用于文本本身)来在Imagick中为水印文本添加阴影。可以通过将填充颜色设置为黑色并偏移文本位置来创建阴影。例如:
$imagick = new \Imagick(realpath('image.png')); $draw = new \ImagickDraw(); $draw->setFillColor('white'); $draw->setFont('Arial'); $draw->setFontSize(50); $imagick->annotateImage($draw, 10, 45, 0, 'Watermark Text'); $imagick->writeImage('watermarked_image.png');
问:如何在Imagick中向多个图像添加水印文本?
答:要向Imagick中的多个图像添加水印文本,可以循环遍历图像并将水印应用于每个图像。以下是一个基本示例:
$draw->setFillColor('red');
以上是PHP主|用Imagick添加文字水印的详细内容。更多信息请关注PHP中文网其他相关文章!