Imagine a friend of yours approaches you one day and would like you to build her a website so she can showcase her photography. She wants to be able to easily upload her photographs and have them watermarked so that people can’t easily steal them. “Don’t worry!” you tell her, because you know there are functions provided by the Imagick extension that makes watermarking images a breeze in PHP.
想象一下,您的一个朋友有一天会接近您,并希望您建立一个网站,以便她展示自己的摄影作品。 她希望能够轻松上传自己的照片并为照片加水印,以使人们无法轻易窃取它们。 “不用担心!” 您告诉她,是因为您知道Imagick扩展提供的功能使PHP中的水印图像变得轻而易举。
This article shares a few pointers on what makes an effective watermark, and then shows you how to use the Imagick functions to add a watermark to your image. Before you get started, make sure the Imagick extension is available on your host. It’s also advisable to find a few pictures you can test the watermark on to gauge it’s effectiveness.
本文分享了一些有关有效水印的内容,然后向您展示了如何使用Imagick函数向图像添加水印。 在开始之前,请确保主机上有Imagick扩展程序可用。 还建议您找到一些可以测试水印的图片,以评估其有效性。
什么造就了良好的水印 (What Makes a Good Watermark)
For a watermark to be effective, it needs to visible against a wide variety of backgrounds. I suggest that you try to find at least one test photo that is very light, and another that is very dark. For example, these two prairie dog pictures from Shutterstock make a good test pair:
为了使水印有效,它需要在多种背景下可见。 我建议您尝试找到至少一张非常亮的测试照片,以及另一张非常暗的照片。 例如,来自Shutterstock的这两张草原土拨鼠图片构成了很好的测试对:
![2 prairie dog pictures 2 prairie dog pictures](https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2011/11/prairiedogs.png)
It’s important that the watermark is transparent enough for you to still be able to see the original image, but opaque enough so it’s difficult for an unscrupulous person to remove. A 40% opacity level is probably a good starting point, and you can increase it or decrease it depending on the situation.
重要的是,水印必须足够透明,以使您仍然能够看到原始图像,但又要足够透明,因此不道德的人很难将其删除。 不透明度40%的水平可能是一个不错的起点,您可以根据情况增加或减少它。
You also want the watermark to be large enough. If you simply put a small watermark in the lower right-hand corner, it’s a prime target for being cropped out. Watermarks that cover a large portion of the original image are more effective. See how iStockPhoto and Shutterstock watermark their work for an example.
您还希望水印足够大。 如果仅在右下角放置一个小水印,则这是裁剪的主要目标。 覆盖原始图像大部分的水印效果更好。 以iStockPhoto和Shutterstock为工作加水印为例。
Finally, the watermark should have contrast. Consider making the watermark dark with a light stroke or visa-versa. This is what iStockPhoto and Shutterstock do, and their mark is easily visible on all of their images whether the original image is light or dark.
最后,水印应具有对比度。 考虑通过轻击或反之使水印变黑。 这就是iStockPhoto和Shutterstock所做的,无论原始图像是浅色还是深色,它们的标记都可以在其所有图像上轻松看到。
For this article I’ll be using this as my watermark, a PNG file with about 40% opacity:
对于本文,我将使用它作为水印,这是一个约40%不透明的PNG文件:
![watermark watermark](https://i-blog.csdnimg.cn/blog_migrate/cf15385233ebec00db1eb3794e943664.webp?x-image-process=image/format,png)
添加水印 (Adding a Watermark)
Adding the watermark is a simple 4-step process: first you open the original image, next you open the watermark, then you overlay the watermark on top of the first image, and then either save or output the result. Here’s the code:
添加水印是一个简单的四步过程:首先打开原始图像,然后打开水印,然后将水印叠加在第一张图像的顶部,然后保存或输出结果。 这是代码:
<?php
// Open the original image
$image = new Imagick();
$image->readImage("/path/to/image.jpg");
// Open the watermark
$watermark = new Imagick();
$watermark->readImage("/path/to/watermark.png");
// Overlay the watermark on the original image
$image->compositeImage($watermark, imagick::COMPOSITE_OVER, 0, 0);
// send the result to the browser
header("Content-Type: image/" . $image->getImageFormat());
echo $image;
You can open images from a path by creating a new instance of the Imagick
class and using its readImage()
method. One nice thing about Imagick is that it can open any time of file that ImageMagick was compiled to support, so you don’t need to explicitly tell it that the file is a JPEG or PNG; it’s smart enough to figure it out on its own.
您可以通过创建Imagick
类的新实例并使用其readImage()
方法从路径打开图像。 关于Imagick的一件好事是,它可以在ImageMagick被编译为支持的文件的任何时间打开,因此您无需明确告诉它文件是JPEG还是PNG。 它足够聪明,可以自行解决。
To overlay the watermark image, you use the compositeImage()
method. In this example, the method accepts four parameters: the first is the image that will be overlaid, the second is a predefined constant representing which type of composition operation Imagick should perform (there’s a whole slew to choose from to achieve different effects), and the third and fourth parameters are the X and Y coordinates at which to place the watermark measured in pixels from the top-left corner.
要覆盖水印图像,请使用compositeImage()
方法。 在此示例中,该方法接受四个参数:第一个是将要覆盖的图像,第二个是预定义的常量,表示Imagick应该执行哪种类型的构图操作( 可以选择一个整体来实现不同的效果),以及第三个和第四个参数是在左上角以像素为单位放置的水印的X和Y坐标。
By default, PHP assumes your script’s output is HTML and sends a text/html Content-Type header automatically. If you output the image, the browser won’t handle it properly since the headers tell it you’re sending text. To avoid your visitors being greeted with a page of gibberish, you need to instruct PHP to send a more appropriate header using header()
before sending the image. Instead of just hard-coding the Content-Type header’s value, the example accesses the image’s type using Imagick itself which is then used to construct an appropriate MIME type on the fly.
默认情况下,PHP假定脚本的输出为HTML,并自动发送text / html Content-Type标头。 如果输出图像,则浏览器将无法正确处理图像,因为标题会告诉您您正在发送文本。 为了避免访问者看到乱码页面,您需要指示PHP在发送图像之前使用header()
发送更合适的标header()
。 该示例不仅仅是使用硬编码Content-Type标头的值,还使用Imagick本身访问了图像的类型,该图像随后用于动态构造适当的MIME类型。
Here’s the end result, a watermarked image:
这是最终结果,带有水印的图像:
![marked-dog alt](https://i-blog.csdnimg.cn/blog_migrate/7607325d34c55581a0fd6c1aca862a3e.webp?x-image-process=image/format,png)
缩放水印 (Scaling the Watermark)
The previous example positioned the watermark at the top-left of the original image. While this approach is fine if you know the size of the original images beforehand since you can create the watermark with the appropriate dimensions, you might want a more robust approach in case the sizes of the original images vary. Such an approach might be to place the watermark in the center of the image, and scaling the watermark beforehand if it is larger than the original image.
前面的示例将水印放置在原始图像的左上角。 如果您可以事先以适当的尺寸创建水印,但如果您事先知道原始图像的大小,则此方法很好,但是,如果原始图像的大小有所变化,则可能需要一种更可靠的方法。 这样的方法可能是将水印放置在图像的中心,如果水印大于原始图像,则预先缩放水印。
<?php
$image = new Imagick();
$image->readImage("/path/to/image.jpg");
$watermark = new Imagick();
$watermark->readImage("/path/to/watermark.png");
// how big are the images?
$iWidth = $image->getImageWidth();
$iHeight = $image->getImageHeight();
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
if ($iHeight < $wHeight || $iWidth < $wWidth) {
// resize the watermark
$watermark->scaleImage($iWidth, $iHeight);
// get new size
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
}
// calculate the position
$x = ($iWidth - $wWidth) / 2;
$y = ($iHeight - $wHeight) / 2;
$image->compositeImage($watermark, imagick::COMPOSITE_OVER, $x, $y);
header("Content-Type: image/" . $image->getImageFormat());
echo $image;
The getImageWidth()
and getImageHeight()
methods return the width and height of an image respectively, measured in pixels. By comparing the width and height of the watermark image to the those of the the original image, you can determine whether or not it is necessary to resize the watermark so it will fit on smaller images.
getImageWidth()
和getImageHeight()
方法分别返回图像的宽度和高度,以像素为单位。 通过将水印图像的宽度和高度与原始图像的宽度和高度进行比较,可以确定是否需要调整水印的大小,以使其适合较小的图像。
Resizing the watermark is accomplished by calling the scaleImage()
method which takes an allowed width and height. The method will scale the image down so that the maximum width is no larger than the allowed width, and the maximum height is no larger than the allowed height, while maintaining the image’s aspect ratio.
调整水印的大小可通过调用scaleImage()
方法来实现,该方法采用允许的宽度和高度。 该方法将按比例缩小图像,以使最大宽度不大于允许的宽度,并且最大高度不大于允许的高度,同时保持图像的长宽比。
And here’s the watermarked image that results from this example:
这是此示例产生的带有水印的图像:
![another watermarked prairie dog image another watermarked prairie dog image](https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2011/10/marked-dog2.png)
摘要 (Summary)
The Imagick library provides a comprehensive image processing API. Indeed, you’ve seen how easy it is to open images files, determine their dimensions and image format, scale them, and overlay one on top of another to watermark them.
Imagick库提供了全面的图像处理API。 确实,您已经看到了打开图像文件,确定其尺寸和图像格式,对其进行缩放以及将一个文件叠加在另一个文件上以对其进行水印处理是多么容易。
Usually I suggest the documentation on php.net if you want to learn more about about the capabilities of an extension, but in the case of Imagick the documentation is spotty. Many methods have just their parameter list given. So if you want to learn more, php.net is still a good place to start but you may have to look for more information for the methods in some other form (the command line application, for example) on the ImageMagick site itself and Google.
通常,如果您想了解有关扩展功能的更多信息,那么我建议您使用php.net上的文档,但是对于Imagick而言,该文档不可靠。 许多方法只给出了其参数列表。 因此,如果您想了解更多信息,php.net仍然是一个不错的起点,但是您可能不得不在ImageMagick网站本身和Google上以其他某种形式(例如,命令行应用程序)寻找有关方法的更多信息。 。