I am using PHP ImageMagic and I am trying to put a border around a Rectangle. I am following this, and this to create the border. It seems to be working fine for them, but for me, if I make the stroke width more than 2, it starts to break.
Here is the code, that I am using
$white = new ImagickPixel("rgb(255, 255, 255)");
$borderWidth = 10;
$draw = new ImagickDraw();
$strokeColor = new ImagickPixel("rgb(255, 255, 255)");
$fillColor = new ImagickPixel("none");
$draw->setStrokeColor($strokeColor);
$draw->setFillColor($fillColor);
//$draw->setStrokeOpacity(1);
$draw->setStrokeWidth(2);
$draw->rectangle(5, 5, 295, 295);
$imagick = new Imagick();
$imagick->newImage(300, 300, "rgb(225, 225, 225)");
$imagick->setImageFormat("png");
$imagick->drawImage($draw);
header("Content-type:image/png");
echo $imagick;die;
This is the result, with $draw->setStrokeWidth(2)
And this is the result, with $draw->setStrokeWidth(5) which obviously seems broken.
What might be the issue?
Related
I am trying to add some text on an Imagick object,
but I am getting spaces and question marks.
$canvas = new Imagick("4093aeb.jpeg");
$canvas->setImageFormat('jpg');
$text = new Imagick();
$text->newImage(800, 800, 'none');
$text->setImageFormat('jpg');
$draw = new ImagickDraw();
$draw->setFontWeight(900);
$draw->setTextKerning(3);
$draw->setFont('./boola.woff');
$draw->setFillColor(new ImagickPixel('#ebebeb'));
$draw->setFontSize(80);
$text->annotateImage($draw, 490, 300, 92, "Home");
$draw->setFillColor(new ImagickPixel('#ebebeb'));
$text->annotateImage($draw, 230, 300, 85, 'Zengyu');
$shadow_layer = clone $text;
$shadow_layer->setImageBackgroundColor(new ImagickPixel('#5f5f5f'));
$shadow_layer->shadowImage(200, 2.5, 0, 0);
$shadow_layer->compositeImage($text, Imagick::COMPOSITE_OVER, 0, 0 );
$canvas->compositeImage($shadow_layer, imagick::COMPOSITE_DEFAULT, 0, 0);
header("Content-type: image/jpg;");
echo $canvas->getImageBlob();
As a result I get
I want the text to be displayed normally, as shown below
Any idea why this is happening? Thanks in advance.
I want to center text over an image, horizontal and vertical. And let it automatically fit (unless what the content is).
When I use the command line, this command works almost perfectly (needs some little finetuning):
magick image.jpg -gravity Center -size 320x140 caption:'This text is resized to best fill the space given.' -compose over -composite ouput.jpg
However, now I want to achieve the same with PHP, but the text does not resize over multiple lines, so I am doing something wrong.
The script I've created so far:
$text = 'This text is resized to best fill the space given.';
$width = 600;
$height = 600;
$textBackground = new ImagickPixel('transparent');
$textColor = new ImagickPixel('#000');
$gradient = new Imagick('image.jpg');
$image = new Imagick();
$image->newImage($width, $height, $textBackground);
$gradient->setImageColorspace($image->getImageColorspace());
$draw = new ImagickDraw();
//$draw->setFillColor($textColor);
$draw->setFontSize( 36 );
$draw->setFont("Alegreya.ttf");
$draw->setGravity (Imagick::GRAVITY_CENTER);
$image->annotateImage($draw, 0, 0, 0, $text);
$gradient->compositeImage($image, Imagick::COMPOSITE_OVER, 0, 0);
$gradient->setImageFormat('jpg');
header('Content-type: image/jpg');
echo $gradient;
The output this generates:
I am trying to create a grayscale mask in Imagemagick (v7.0.11) that behaves like a layer mask in Photoshop where white areas are completely opaque and black areas are fully masked.
function grayscaleMaskTest () {
//Create a black and white mask
$mask = new Imagick();
$mask->newImage(300, 300, "#ffffff");
$mask->setImageType(IMAGICK::IMGTYPE_GRAYSCALE);
$mask->setImageFormat('gif');
//draw black circle
$draw = new ImagickDraw();
$draw->setStrokeWidth(1);
$draw->setStrokeOpacity(1);
$draw->setStrokeColor(new ImagickPixel("#000000"));
$draw->setFillColor(new ImagickPixel("#000000"));
$draw->circle(300/2, 300/2, 300/2, 300/2 + 100);
$mask->drawImage($draw);
//$mask->writeImage('C:\Users\Mike\Documents\images\mask.png'); //export mask
//Create final image
$final = new Imagick();
$final->newImage(300, 300, "#FF0000");
//Not sure if I had this right but tried writing the mask data to the alpha channel
//$final->compositeImage($mask, IMAGICK::COMPOSITE_COPYOPACITY, 0, 0, IMAGICK::CHANNEL_ALPHA);
$final->compositeImage($mask, IMAGICK::COMPOSITE_COPYOPACITY, 0, 0);
$final->writeImage('C:\Users\Mike\Documents\images\final.png');
}
The mask looks like this :
The desired result from this code if it worked would be this (minus the fake transparency) :
With help from #fmw42 this ended up working. Thanks!
//Create a black and white mask
$mask = new Imagick();
$mask->newImage(300, 300, "#ffffff");
//draw black circle
$draw = new ImagickDraw();
$draw->setStrokeWidth(1);
$draw->setStrokeOpacity(1);
$draw->setStrokeColor(new ImagickPixel("#0"));
$draw->setFillColor(new ImagickPixel("#0"));
$draw->circle(300/2, 300/2, 300/2, 300/2 + 100);
$mask->drawImage($draw);
$mask->setImageMatte(false); //<-------This got it going!
//Create final image
$final = new Imagick();
$final->newImage(300, 300, "#FF0000");
$final->compositeImage($mask, imagick::COMPOSITE_COPYOPACITY, 0, 0);`
How can I draw image with smooth edges using setImageClipMask?
My code produces like this:
which has sharp jagged edges where the edge of the clip mask is.
The code I am using:
// Draw clip mask
$clipMask = new \Imagick();
$clipMask->newPseudoImage($width, $height, "canvas:white");
$draw = new \ImagickDraw();
$draw->setFillColor(new ImagickPixel('black'));
$draw->polygon($myCoordinates);
$clipMask->drawImage($draw);
// Set mask
$img_main->setImageClipMask($clipMask);
// Draw image
$img_main->compositeImage($myImage, Imagick::COMPOSITE_DEFAULT, $x, $y);
tl:dr don't use masks use a gradient instead.
Masks are a binary choice; the pixel either gets through or it doesn't and are designed to have sharp edges.
Gradients (which don't have to be linear) allow for effects to be applied smoothly. The code below generates a gradient and then uses it to blend between the two images smoothly.
Gradient generated:
Output image:
<?php
$background = new \Imagick(realpath('./Skyline_400.jpg'));
$overlay = new \Imagick(realpath('./background.jpg'));
$overlay->scaleimage(
$background->getImageWidth(),
$background->getImageHeight()
);
$gradient = createGradient($background);
//If you need to see the gradient for debugging.
$gradient->setImageFormat("png");
$gradient->writeImage("./gradient.png");
$gradient2 = clone $gradient;
//The overlay needs to have the gradient reversed
$gradient2->negateimage(false);
$gradient2->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
$background->compositeImage($gradient2, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);
$gradient->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
$overlay->compositeimage($gradient, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);
//Create a new canvas to render everything in to.
$canvas = new \Imagick();
$canvas->newImage($gradient->getImageWidth(), $gradient->getImageHeight(), new \ImagickPixel('black'));
//Blend background into canvas
$canvas->compositeimage($background, \Imagick::COMPOSITE_BLEND, 0, 0);
//Blend overlay into canvas
$canvas->compositeimage($overlay, \Imagick::COMPOSITE_BLEND, 0, 0);
//Output the final image
$canvas->setImageFormat('png');
$canvas->writeImage("./output_test.png");
// Create a gradient/mask to allow images to be blended smoothly.
function createGradient(\Imagick $background)
{
$myCoordinates = [
['x' => 20, 'y' => 20,],
['x' => 360, 'y' => 20,],
['x' => 350, 'y' => 350,],
['x' => 25, 'y' => 350,],
];
$backgroundMask = new \Imagick();
$backgroundMask->newPseudoImage(
$background->getImageWidth(),
$background->getImageHeight(),
'canvas:white'
);
$draw = new \ImagickDraw();
$draw->setFillColor(new ImagickPixel('black'));
$draw->polygon($myCoordinates);
$backgroundMask->setImageFormat('png');
$backgroundMask->drawImage($draw);
// Blur the edges to make the transition between black and white
// be smooth
$backgroundMask->blurImage(2, 0.5);
return $backgroundMask;
}
I just want to get the basic idea of how to draw a circle with php5 imagemagick.
I have looked at the page, http://php.net/manual/en/imagickdraw.circle.php
but the example there is too confusing. I want to just draw a circle then mess around with that. Can someone give me a simple php5 imagemagick circle example?
I have tried:
<?php
header("Content-type: image/jpeg");
$circle = new ImagickDraw();
$draw->circle (10, 10, 60, 10);
//echo $circle;
?>
any numerous variants, but I cant get a circle drawn.
I hope this is what you're looking for:
<?php
$draw = new ImagickDraw ();
//given that $x and $y are the coordinates of the centre, and $r the radius:
$draw->circle ($x, $y, $x + $r, $y);
?>
Danak on the php chat page provided me with this link, Which provides an active example.
http://www.phpimagick.com/ImagickDraw/circle
The variable names are concise and descriptive,
and the example makes it easy for me to understand what is going on.
function circle($strokeColor, $fillColor, $backgroundColor, $originX, $originY, $endX, $endY) {
//Create a ImagickDraw object to draw into.
$draw = new \ImagickDraw();
$strokeColor = new \ImagickPixel($strokeColor);
$fillColor = new \ImagickPixel($fillColor);
$draw->setStrokeOpacity(1);
$draw->setStrokeColor($strokeColor);
$draw->setFillColor($fillColor);
$draw->setStrokeWidth(2);
$draw->setFontSize(72);
$draw->circle($originX, $originY, $endX, $endY);
$imagick = new \Imagick();
$imagick->newImage(500, 500, $backgroundColor);
$imagick->setImageFormat("png");
$imagick->drawImage($draw);
header("Content-Type: image/png");
echo $imagick->getImageBlob();
}