ImageMagick PHP - Distort text and annotate on image - php

Is it possible to distort a text and annotate it on an image with ImageMagick (PHP)? Or do I have to create an image from the text, distort it and then paste it on my base image?
I have a coffee mug and want to add text. I want to add a slight arc to my text to have a threedimensional look on my mug.
I tried around with arched font:
http://www.imagemagick.org/Usage/fonts/#arch
But in my code example I cannot get it to work because the text is $draw = new ImagickDraw(); and I cannot distort it or use arched font. I always end up with my whole image being distorted because the distortion only works on images like $image = new Imagick('original/'.$id.'.jpg')
Any hints or advice is greatly apprciated. I need a font with a little concave arch like in this example here:
http://www.imagemagick.org/discourse-server/viewtopic.php?t=13901
I cannot get this to work in PHP.
$fontpath = 'fonts/';
$id = $_REQUEST["id"];
$text1 = $_REQUEST['text1'];
$text2 = $_REQUEST['text2'];
$fontname1 = $_REQUEST['fontname1'];
$fontname2 = $_REQUEST['fontname2'];
$x_coordinate1 = $_REQUEST['x_coordinate1'];
$x_coordinate2 = $_REQUEST['x_coordinate2'];
$y_coordinate1 = $_REQUEST['y_coordinate1'];
$y_coordinate2 = $_REQUEST['y_coordinate2'];
$pointsize1 = $_REQUEST['pointsize1'];
$pointsize2 = $_REQUEST['pointsize2'];
$fill1 = $_REQUEST['fill1'];
$fill2 = $_REQUEST['fill2'];
$stroke1 = $_REQUEST['stroke1'];
$stroke2 = $_REQUEST['stroke2'];
/* Create some objects */
//$image = new Imagick();
$draw = new ImagickDraw();
/* New image */
$image = new Imagick('original/'.$id.'.jpg');
/* Text color */
$draw->setFillColor($fill1);
/* Font properties */
$draw->setFont($fontpath.$fontname1);
$draw->setFontSize( $pointsize1 );
/* Create text */
/* Center is important */
$draw->setGravity (Imagick::GRAVITY_CENTER);
$image->annotateImage($draw, $x_coordinate1, $y_coordinate1, 0, $text1);
/* Text2 color */
$draw->setFillColor($fill2);
/* Font2 properties */
$draw->setFont($fontpath.$fontname2);
$draw->setFontSize( $pointsize2 );
$draw->setGravity (Imagick::GRAVITY_CENTER);
$image->annotateImage($draw, $x_coordinate2, $y_coordinate2, 0, $text2);
/* Give image a format */
$image->setImageFormat('jpg');
/* Output the image with headers */
header('Content-type: image/jpg');
echo $image;

The comment from fmw42 worked best for my problem. I created text as an image with transparent background then distorted and finally composited on another image.

Related

PHP imagick COMPOSITE_DSTIN result has black background

I try to set a text gradient from this solution here https://www.sitepoint.com/community/t/gd-text-gradient/82127/9
But the background color of the final image is black, I try $im->flattenImages and $img->setBackgroundColor but it's not working.
$im = new Imagick();
$draw = new ImagickDraw();
$draw->setFontSize(90);
$draw->setFillColor(new ImagickPixel("black"));
$draw->setTextEncoding('UTF-8');
$draw->setGravity(Imagick::GRAVITY_CENTER);
$metric = $im->queryFontMetrics($draw, $text);
$width = $metric['textWidth'];
$height = $metric['textHeight'];
/* Create and save the gradiant */
$Imagick = new Imagick();
$Imagick->newPseudoImage($height, $width, "gradient:#FB7F4C-#FF409C");
/*** rotate the image ***/
$Imagick->rotateImage(new ImagickPixel(), 270);
$Imagick->setImageFormat('png');
$Imagick->writeImage("gradiant.png");
/* Create and save the canvas */
$im->newPseudoImage($width, $height, "null:");
$im->setImageFormat('png');
$im->writeImage("canvas.png");
/* Add the text to the canvas ( Make the mask )*/
$im = new Imagick("canvas.png");
// Write the text on the image
$im->annotateImage($draw, 0, 0, 0, $text);
$im->setImageBackgroundColor("transparent"); // <= Here
/* Final image */
$canvas = new Imagick("gradiant.png");
$canvas->compositeImage($im, imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA);
$canvas->setImageFormat('png');
$canvas->writeImage(__DIR__ . "/../../final.png");
header('Content-Type: image/' . $im->getImageFormat());
echo $canvas;
unlink("canvas.png");
unlink("gradiant.png");
I found after the COMPOSITE_DSTIN the background color goes black, I try many way but its not working
How to remove black background?
I'm solved it by adding alphachannel
I try $canvas->setImageAlphaChannel(Imagick::ALPHACHANNEL_RESET); and after that the background stay transparent
UPDATE
After I updated my imagick library it's stop working and search for similar issue and found this Imagemagick compose image inverted
And here the code that works well
$canvas->transformImageColorspace(Imagick::COLORSPACE_SRGB);

Imagemagick background gradient

I've got some basic code working to generate an image with a solid background. However I was wondering how I can make a gradient. This is my code:
<?php
function process($inputdata)
{
/* Create some objects */
$image = new Imagick();
$draw = new ImagickDraw();
$pixel = new ImagickPixel( 'gray' );
/* New image */
$image->newImage(400, 300, $pixel);
/* Black text */
$draw->setFillColor('black');
/* Font properties */
$draw->setFont('Bookman-DemiItalic');
$draw->setFontSize( 30 );
/* Create text */
$image->annotateImage($draw, 10, 45, 0, $inputdata);
/* Give image a format */
$image->setImageFormat('png');
/* Output the image with headers */
header('Content-type: image/png');
echo $image;
return;
}
The closest code I could find is something like this:
$gradient = new Imagick();
$gradient->newPseudoImage(400, 300, 'gradient:blue-red');
But I don't know how I then combine the gradient with the text.
Please use compositeImage function. It combine one image into another. Create one Imagick instance with gradient, second one with text and alpha channel background, and combine them into the one.
Reference: http://php.net/manual/en/imagick.compositeimage.php
$text = 'The quick brown fox jumps over the lazy dog';
$width = 1000;
$height = 1000;
$textBackground = new ImagickPixel('transparent');
$textColor = new ImagickPixel('#000');
$gradient = new Imagick();
$gradient->newPseudoImage($width, $height, 'gradient:blue-red');
$image = new Imagick();
$image->newImage($width, $height, $textBackground);
$gradient->setImageColorspace($image->getImageColorspace());
$draw = new ImagickDraw();
$draw->setFillColor($textColor);
$draw->setFontSize( 10 );
$image->annotateImage($draw, 10, 45, 0, $text);
$gradient->compositeImage($image, Imagick::COMPOSITE_MATHEMATICS, 0, 0);
$gradient->setImageFormat('png');
header('Content-type: image/png');
echo $image;

Image editing using ImageMagick PHP library

I am developing image editor, i successfully write text on images on position x,y, now i need to draw a white image on image that is called white out. white image will be drawn at position cord X, cord Y and dynamic size of image width, height. i write code but i am not getting the image on right coordinates and height width of image.
here is my image rendering function.
$image = new Imagick('image.jpg');
$diagnose=$this->input->post('diagnoses');
$fontsize=$this->input->post('fontsize');
$fontstyle=$this->input->post('fontstyle');
$cordX = $this->input->post('posX');
$cordY = $this->input->post('posY');
$font_size = 20;
// Watermark text
//$diagnose = "Hello world.{newline}It's a beautiful day.";
$textlinesArray = explode("{newline}",$diagnose);
// Create a new drawing palette
$draw = new ImagickDraw();
// Set font properties
$draw->setFont('Arial');
$draw->setFontSize($font_size);
$draw->setFillColor('black');
// Position text at the bottom-right of the image
$draw->setGravity(Imagick::GRAVITY_NORTHWEST);
$i = 0;
foreach ($textlinesArray as $index => $text) {
$newY = ($i * $font_size) + $cordY;
//echo $newY . "</br>";
//echo $text;
// Draw text on the image
$image->annotateImage($draw, $cordX, $newY,0, $text);
$i++;
}
$draw->setFillColor('magenta'); // Set up some colors to use for fill and outline
$draw->setStrokeColor( new ImagickPixel( 'cyan' ) );
$draw->setStrokeWidth(2);
$draw->rectangle($cordX, $cordY, 200, 300); // Draw the rectangle
$image->drawImage( $draw );
// Set output image format
$image->setImageFormat('png');
// Output the new image
header('Content-type: image/png');
echo $image;
here is the output, i need that color box dynamic width height and position

Mask text with imagick php

The following code is a very basic example of imagick's Imagick::annotateImage() function. How would I go about masking the top half of the text while retaining the background image?
<?php
/* Create some objects */
$image = new Imagick('bg.jpg');
$draw = new ImagickDraw();
$pixel = new ImagickPixel( 'transparent' );
/* New image */
$image->newImage(800, 75, $pixel);
/* Black text */
$draw->setFillColor('black');
/* Font properties */
$draw->setFont('Bookman-DemiItalic');
$draw->setFontSize( 30 );
/* Create text */
$image->annotateImage($draw, 10, 45, 0, 'The quick brown fox jumps over the lazy dog');
/* Give image a format */
$image->setImageFormat('png');
/* Output the image with headers */
header('Content-type: image/png');
echo $image;
?>

Generate dummy images local via CLI

I need to generate some (thousands) dummy images local to test a CLI based content converter. The file names are set.
A name list as example:
fw4df.jpg
antotherName.jpg
and so on.
I would write a script using ImageMagick extension to create those images with some dummy content.
Any suggestion to solve this more clever?
I would do this for 1,000 images:
head -1000 /path/to/your/word/list |
while read word; do \
echo -n $word | convert label:#- "$word.jpg" \
done
You get
ImageMagick ships with some built in images. The most common ones are wizard:, rose:, and logo:
convert wizard: wizard.jpg
convert rose: rose.jpg
convert logo: logo.jpg
Edit
If you just want a clever PHP function, I would continue to use PseudoImages to simplify everything.
function createPseudoImage($label_text, $width, $height, $label_format='No. %d') {
$background = new Imagick;
$background->newPseudoImage($width, $height, 'PATTERN:HORIZONTALSAW');
$label = new Imagick();
$label->setBackgroundColor('transparent');
$label_width = $background->getImageWidth() * 0.8;
$label_height = $background->getImageHeight() * 0.8;
$label_text = sprintf('CAPTION:'.$label_format, $label_text);
$label->newPseudoImage($label_width, $label_height, $label_text);
$offset_x = $background->getImageWidth()/2 - $label->getImageWidth()/2;
$offset_y = $background->getImageHeight()/2 - $label->getImageHeight()/2;
$background->compositeImage($label, Imagick::COMPOSITE_ATOP, $offset_x, $offset_y);
return $background;
}
$fpo = createPseudoImage(49, 500, 200);
$fpo->writeImage('/tmp/out.png');
But YMMV
I wrote a script based on the PHP doc example. Perhaps it will help someone:
<?php
generateDummyImages(array("test.jpg", "test2.jpg"));
/**
*
* #param array $files
* #param string $dataOutPath
*/
function generateDummyImages($files, $dataOutPath = "") {
$width = 500;
$height = 500;
$imageCompressionQuality = 90;
foreach($files as $i => $filename) {
/* Create a new imagick object */
$im = new Imagick();
/* Create new image. This will be used as fill pattern */
$im->newPseudoImage($width, $height, "gradient:red-black");
/* Create imagickdraw object */
$draw = new ImagickDraw();
/* Start a new pattern called "gradient" */
$draw->pushPattern('typo', 0, 0, $width, $height);
/* Composite the gradient on the pattern */
$draw->composite(Imagick::COMPOSITE_OVER, 0, 0, $width, $height, $im);
/* Close the pattern */
$draw->popPattern();
/* Use the pattern called "gradient" as the fill */
$draw->setFillPatternURL('#typo');
/* Set font size to 52 */
$draw->setFontSize(100);
/* Annotate some text */
$draw->annotation($width / 2 - 100, $height / 2, "No. " . $i);
/* Create a new canvas object and a white image */
$canvas = new Imagick();
$canvas->newImage($width, $height, "white");
/* Draw the ImagickDraw on to the canvas */
$canvas->drawImage($draw);
/* 1px black border around the image */
$canvas->borderImage('black', 1, 1);
/* Set the format to PNG */
$canvas->setImageFormat('jpg');
$canvas->setImageCompression(Imagick::COMPRESSION_JPEG);
$canvas->setCompressionQuality($imageCompressionQuality);
/* Output the image */
$canvas->writeimage($dataOutPath . $filename);
echo "Image generated: " . $dataOutPath . $filename . PHP_EOL;
}
}
?>

Categories