📜 ⬆️ ⬇️

MagickWand - shadows and rounded corners

Inspired by the topic of habrauzer apelsyn Photoshop in PHP
I took up writing the engine for the card service - for friends, for free. Such work is good because you can set up experiments and learn something new and interesting in the process - no one can rush and remind you of dates.
In this work for the first time I had to face the interface to ImageMagick called MagickWand
I figured out how to make thumbnails quickly, despite the fact that the documentation, to put it mildly, is very laconic. In the same way, adding inscriptions and backgrounds to the picture almost did not cause any questions.
But the soul wanted beauty.
In particular, rounded corners and shadows under thumbnails.
I knew that it was possible to do things, but the whole catch was that in the mentioned post everything was done with the help of Imagick, and I already had MagickWand! Google, habr and thematic blogs did not give anything, so I had to reinvent the wheel myself.
After some problems, briefly beating your head against the wall and experimenting with image overlay modes in MagickWand was born. .

<?php
$img = '../images/card1.jpg'; //
$card=NewMagickWand();
MagickReadImage($card, $img); // MagickWand
$card = MagickTransformImage($card, NULL, 'x190'); //

//

$pr_width = MagickGetImageWidth($card); //
$pr_height = MagickGetImageHeight($card); //

$black=NewPixelWand();
PixelSetColor($black, "#000000"); // PixelWand - .

$rounded=NewDrawingWand(); //
DrawSetFillColor($rounded, $black); //
DrawSetFillAlpha($rounded, 1); //- (), 0 - , 1 -
DrawRoundRectangle($rounded, 3, 3, $pr_width-6, $pr_height-6, 15, 15); //

$border=NewMagickWand(); // ,
MagickNewImage($border, $pr_width, $pr_height, "#ffffff"); //
MagickSetImageFormat($border, 'png'); //

MagickDrawImage($border, $rounded); //

// ---------- ---------------- //
MagickCompositeImage($card, $border, MW_BlendCompositeOp, 0, 0); // , - MW_BlendCompositeOp ( )
// ------------ ----------------- ----------------- ----------------- ---------------- //
//
$border_c=NewPixelWand(); //
PixelSetColor($border_c,"#eeeeee"); //

$rounded_b=NewDrawingWand(); //
DrawSetStrokeColor($rounded_b, $border_c); //
DrawSetStrokeWidth($rounded_b, 1); //
DrawSetFillOpacity($rounded_b, 0); // , -
DrawRoundRectangle($rounded_b, 3, 3, $pr_width-6, $pr_height-6, 15, 15); // -
MagickDrawImage($card, $rounded_b);

/* */

//
$sh_border=NewMagickWand(); //
MagickNewImage($sh_border, $pr_width, $pr_height, "#ffffff"); //
MagickSetImageFormat($sh_border, 'png');

$sh_color=NewPixelWand(); //
PixelSetColor($sh_color, "#aaaaaa"); // -

$sh_rounded=NewDrawingWand(); // ,
DrawSetFillColor($sh_rounded, $sh_color); //
DrawSetFillAlpha($sh_rounded, 1); // -
DrawRoundRectangle($sh_rounded, 6, 6, $pr_width-3, $pr_height-3, 15, 15); // ( - )

MagickDrawImage($sh_border, $sh_rounded); //
MagickBlurImage($sh_border, 3, 3); // blur () -

$sh_fill_color=NewPixelWand(); // -
PixelSetColor($sh_fill_color, "#ffffff"); //

$rounded_fill=NewDrawingWand(); // -
DrawSetFillColor($rounded_fill, $sh_fill_color); //
DrawSetFillAlpha($rounded_fill, 1); //
DrawRoundRectangle($rounded_fill, 3, 3, $pr_width-6, $pr_height-6, 15, 15); // - ,
MagickDrawImage($sh_border, $rounded_fill); //

MagickCompositeImage($sh_border, $card, MW_MultiplyCompositeOp, 0, 0); // , - MW_MultiplyCompositeOp.

header('Content-type: image/jpeg'); // -

MagickEchoImageBlob($sh_border); //

?>

Description of the action algorithm

To create rounded corners, we draw a rectangle the size of our image (white), and on it is a slightly smaller rectangle with rounded corners (black). The resulting design is glued to the original image, but with the blending mode, which cuts off the image details that are under white and leaves what is under black. It remains the same rectangular picture, but with a white frame with rounded corners. Then on the picture we draw a frame that repeats the original rectangle with rounded corners.
')
For the shadow, in the same way, we draw a white frame with a black rounded rectangle inside, which is slightly shifted relative to the original image (the one from which the shadow will fall). Then we repeat the original image with a white rectangle. Thus, we only have on the white rectangle that piece of the shadow that we need. Glue it on top of the original image.

As a result, we get something like this:
image
In the future, I plan from this code to make a function that can be fed any pictures with a given thumbnail size, and it will give the same thumbnail with rounded corners and shadow. As part of this project, such a function is not needed yet.

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


All Articles