📜 ⬆️ ⬇️

Overlaying text and images onto an image using MagickWand and GD libraries

MagickWand is one of the libraries that access the ImageMagic software package for working with images in PHP. Consider the features of the overlay text and graphics in it. ImageMagic is said to be very fast and gives a better quality result (but not as common as GD). For one check it out.

The general script code will be as follows:

$new_image = NewMagickWand(); //  MagickWand MagickReadImage($new_image, 'image.png'); //     $w = MagickGetImageWidth($new_image); //   $h = MagickGetImageHeight($new_image); /* ---   --- */ MagickSetImageFormat($new_image, 'jpeg'); MagickWriteImage($new_image, 'newimage.jpeg'); //  // ClearMagickWand($new_image); //       DestroyMagickWand($new_image); 


Now consider the image processing code in more detail. For example, we will impose a text copyright on the photo. This can be done in several ways:
')
1. Apply a pre-prepared translucent copyright image using MagickCompositeImage

 $watermark = NewMagickWand(); MagickReadImage($watermark, 'copyright.png'); //   $wc = MagickGetImageWidth($watermark); $hc = MagickGetImageHeight($watermark); MagickCompositeImage($new_image, $watermark, MW_OverCompositeOp, $w-$wc, $h-$hc); //     ClearMagickWand($watermark); //      DestroyMagickWand($watermark); 


2. Apply a pre-prepared translucent copyright image using DrawComposite

 $watermark = NewMagickWand(); MagickReadImage($watermark, 'copyright.png'); $watermark_drawing = NewDrawingWand(); //  DrawingWand   DrawSetGravity($watermark_drawing, MW_SouthEastGravity); //       DrawComposite($watermark_drawing, MW_OverCompositeOp, 0, 0, 0, 0, $watermark); //    MagickDrawImage($new_image, $watermark_drawing); //     ClearMagickWand($watermark); DestroyMagickWand($watermark); ClearDrawingWand($watermark_drawing); DestroyDrawingWand($watermark_drawing); 

The result of these two methods is the following:

image

Execution time is similar. In the first case, it jumps from 20 to 400ms. Take the abstract mean value of 200ms. In the second case, it practically does not depend on the size of the image and other factors and amounted to 160ms.

3. Generate copyright text and apply using MagickAnnotateImage

 //   $watermark_drawing = NewDrawingWand(); DrawSetFont($watermark_drawing, 'copyright.ttf'); DrawSetFontSize($watermark_drawing, 12); DrawSetGravity($watermark_drawing, MW_NorthWestGravity); //   $pixel_wand = NewPixelWand(); PixelSetColor($pixel_wand, 'black'); PixelSetOpacity($pixel_wand, 0.6); DrawSetFillColor($watermark_drawing, $pixel_wand); //        MagickAnnotateImage($new_image, $watermark_drawing, $w-15, $h-8, -90,' '); ClearDrawingWand($watermark_drawing); DestroyDrawingWand($watermark_drawing); 


4. The same, but with DrawAnnotation

 $watermark_drawing = NewDrawingWand(); DrawSetFont($watermark_drawing, 'copyright.ttf'); DrawSetFontSize($watermark_drawing, 12); DrawSetGravity($watermark_drawing, MW_NorthWestGravity); DrawRotate($watermark_drawing, -90); $pixel_wand = NewPixelWand(); PixelSetColor($pixel_wand, 'black'); PixelSetOpacity($pixel_wand, 0.6); DrawSetFillColor($watermark_drawing, $pixel_wand); DrawAnnotation($watermark_drawing, 8-$h, $w-15, ' '); //    . // ,     90°     «»,      MagickDrawImage($new_image, $watermark_drawing); ClearDrawingWand($watermark_drawing); DestroyDrawingWand($watermark_drawing); 

The result of these two methods is the following:

image

The inscription is a little clearer, but it rather indicates that Photoshop is too blurry the text in the source file for the first methods.

The speed of the methods are identical. Time jumps much. For small images is 20ms and reaches 300ms at 2560 × 1600. Take the average value of 150. Again, abstract.

Conclusion: To insert a copyright using MagickWand, the best way to do it is with DrawComposite. It is universal (you can insert not only text) and it works at a predictable time. The original image for it can be prepared in 3 or 4 ways.

GD Graphics Library is likely to be on any server. It can do the same in it:

 list($w, $h) = getimagesize('image.png'); //    $new_image = imagecreatefrompng('image.png'); //   /* ---   --- */ imagejpeg($new_image, 'newimage.jpeg') // imagedestroy($new_image); 


1. Using the prepared image

 list($cw, $ch) = getimagesize('copyright.png'); $watermark = imagecreatefrompng('copyright.png'); imagecopy($new_image, $watermark, $w-$cw, $h-$ch, 0, 0, $cw, $ch); //  imagedestroy($watermark); //  


image

2. Text Generation by GD

 $color = imagecolorallocatealpha($new_image, 0, 0, 0, 60); //     60% imagettftext($new_image, 10, 90, $w-7, $h-12, $color, 'copyright.ttf', ' '); //        


image

The operation time in the first case was from 0.2 to 0.7 ms, depending on the image size, in the second - 30% longer.

Frankly, he was surprised when he saw that GD works almost 1000 times faster. True, it was the image processing algorithm that measured, without opening, saving and converting to another format. Also did not take into account the amount of memory occupied, so the data are not very suitable for practical use. Measuring the performance of entire functions with different file types has shown that GD runs up to 10 times faster on small files. The most common sizes (3–8 megapixels) of the library are processed at the same speed (valid only for my hosting). MagickWand (ImageMagic) is loved for the best quality scaling. Again, this is true only for complex photos. Clear MW Contours Blur Too Much

imageimage

Interestingly, the weight of such a png-image (right) turned out to be 1.2 KB against 6 KB in GD. And all from the fact that GD did not guess to change the palette to 8-bit.

So check the speed on your hosting (I tested at McHhost), choose the quality based on your needs and then give preference to one or another library, or rather throw a coin ;-)

Bonus
A little about the quality settings

In MagickWand, quality settings are set before saving.

 MagickSetImageCompressionQuality($new_image, $quality); MagickSetImageFormat($new_image, 'jpeg'); MagickWriteImage($new_image, 'newimage.jpeg'); //  

Here $ quality compression ratio is from 0–100 for jpeg and 0–80 for png. Does not affect gif.
for jpeg:
0, null - default compression ~ 85
1..100 - gradation from terrible quality to perfect

for png, since this is a format without loss of quality, only affects the weight of the image and, accordingly, the time it is processed by the server:
0, null - the default compression is the highest (in this case, the image weight is minimal)
1..80 - gradation from low to high degree of compression (but the greatest compression is at 0)

Even in MagickWand, you can specify the type of compression, but in the case of jpeg, png, gif, it does not affect anything.
MagickSetImageCompression ($ image, MW_JPEGCompression);

In GD, quality is set in save functions.

 imagejpeg($new_image, 'newimage.jpeg', $quality) imagepng($new_image, 'newimage.png', $quality) imagegif($new_image, 'newimage.gif') //gif    

Here $ quality compression ratio is from 0–100 for jpeg and 0–9 for png.
For jpeg:
null - default compression 75
0..100 - gradation from terrible quality to perfect. Almost the same as MagickWand

for png:
null - default compression 0 (bad compression)
0..9 - gradation from low to high degree of compression. With a value of 9, the weight of the picture is approximately the same as with 0 in MagickWand

Source: https://habr.com/ru/post/159209/


All Articles