I'm working on (what should be) a simple script that will add text to an image. After going over my script several times looking for any mistakes I finally decided to try running a sample from php.net and I encountered the same, nondescript, error: "Failed to query the font metrics". Here's the code:
/* Text to write */
$text = "Hello World!";
/* Create Imagick objects */
$image = new Imagick();
$draw = new ImagickDraw();
$color = new ImagickPixel('#000000');
$background = new ImagickPixel('none'); // Transparent
/* Font properties */
$draw->setFont('Arial');
$draw->setFontSize(50);
$draw->setFillColor($color);
$draw->setStrokeAntialias(true);
$draw->setTextAntialias(true);
/* Get font metrics */
$metrics = $image->queryFontMetrics($draw, $text);
/* Create text */
$draw->annotation(0, $metrics['ascender'], $text);
/* Create image */
$image->newImage($metrics['textWidth'], $metrics['textHeight'], $background);
$image->setImageFormat('png');
$image->drawImage($draw);
/* Save image */
file_put_contents('/tmp/file.png', $image);
I can not for the life of me find any information via google about this error. Nor can I find adequate documentation on this method or potential causes of failure. Basically, I'm stumped. If anyone could provide insight or a fix it would be greatly appreciated.
ImageMagic version: ImageMagick 6.6.5-10 2011-04-06 Q16
Imagick module version: 3.1.0b1
have you tried cli version ? is imagemagick installed on server ? if yes
then run a command like
system('convert -background lightblue -fill blue \
-font Candice -pointsize 72 label:Anthony \
label.gif ');
see if you have imagenamed label.gif in server after running script.
for your reference http://www.imagemagick.org/Usage/text/
For those having similar issues, the PHP Imagick exceptions aren't always the most descriptive. I could have saved myself a lot of time examining the output from the Image Magic application installed on the server first. Just something to keep in mind. To view a list of the currently installed delegates(modules) use the command convert -list configure and examine the line that starts with "DELEGATES" from the output. If you encounter the same error, I recommend checking here first. I found I was missing the freetype and ghostscript delegates. After installing the dependancies and a quick recompile of ImageMagick everything works like a charm.
Related
I am using php 7.0.19 and ImageMagick 6.9.6-4 on a FreeBSD 11.0 server. I use imagemagick for quite a few things, but I am just getting started with using it to overlay text on top of my images. The problem I'm having is that any time I try to use the annotateImage functionality an error is thrown that simply says 'Unable to annotate image.'
I have looked through quite a few questions related to annotateImage here on stackoverflow and I have checked the docs to see if I could resolve the issue on my own, but I'm stuck. On other annotateImage questions I have seen that some people have trouble due to not having a specific font installed, and that may be my problem as well, but I have tried placing a font file (the ttf file) in the same directory as my script and I am still having the same issue.
Running convert -list font returns an empty result, indicating that there are no fonts that imagemagick has direct/default access to; however, I was thinking that by including the font file in the same directory as my script I could make it work anyway. Perhaps this is a mistaken assumption?
Here is the code I am using for my test:
$imagick = new Imagick('originalImage.jpg');
$draw = new ImagickDraw();
$draw->setFillColor('#ffffff');
$draw->setFont('ARIAL.TTF');
$draw->setFontSize(20);
$imagick->annotateImage($draw, 20, 100, 0, 'The quick fox jumps over the lazy dog');
$imagick->drawImage($draw);
$imagick->writeImage('finalImage.jpg');
I have also tried other example scripts that don't require an original image, and received the same error. For example, this script produces the same error:
$image = new Imagick();
$draw = new ImagickDraw();
$pixel = new ImagickPixel( 'gray' );
$image->newImage(800, 75, $pixel);
$draw->setFillColor('black');
$draw->setFont('ARIAL.TTF');
$draw->setFontSize( 30 );
$image->annotateImage($draw, 10, 45, 0,
'The quick brown fox jumps over the lazy dog');
$image->setImageFormat('png');
header('Content-type: image/png');
echo $image;
With this simple test I was expecting to add 'The quick fox jumps over the lazy dog' over the top of my image, but instead an exception is thrown and the error message simply says: Unable to annotate image.
Any ideas or suggestions on how I can resolve the error?
Thanks!
Through posting this question on the imagemagick forum, I was able to get it figured out. The problem was that our ImageMagick install is missing the 'freetype' delegate, which is required for rendering text from fonts.
Thanks!
I want to use Imagick API for PHP instead of runnung command line in my PHP code.
exec("convert -gravity Center -size 200x200 -fill black -font Arial -pointsize 20 pango:\"Hello World!\" output.png");
for above command I have following Imagick API code:
<?php
$img = new Imagick();
$draw = new ImagickDraw();
$draw->setFont("Arial");
$draw->setFontSize(20);
$draw->setGravity( Imagick::GRAVITY_CENTER );
$img->newImage( 200, 200, "black", "png" );
//Pango code for Hello World!
$img->writeImage("output.png");
?>
But I could not find equal method/option for Pango. Do you know how can use Pango in Imagick API?
Just improving Aite's answer by adding background color.
$img = new Imagick();
$img->setBackgroundColor(new ImagickPixel('black'));
$img->setFont("Arial");
$img->setPointSize(20);
$img->setGravity( Imagick::GRAVITY_CENTER );
$img->setImageFormat('jpg');
//Pango code for Hello World!
$img->newPseudoImage(200, 200, "pango:Hello World");
$img->writeImage("output.png");
The part pango:\"Hello World!\" is 'the name of a file' in ImageMagick. This means you should call readImage to 'read' the pango image:
$img->readImage("pango:\"Hello World!\"");
This will only work if ImageMagick is compiled with support for pango.
First of all, you don't need the ImagickDraw object, you only need to set your options to the Imagick object then to create/call new pseudo image (with pango: prefix) instead of regular new image method:
$img = new Imagick();
$img->setFont("Arial");
$img->setPointSize(20);
$img->setGravity( Imagick::GRAVITY_CENTER );
$img->setImageFormat('jpg');
//Pango code for Hello World!
$img->newPseudoImage(200, 200, "pango:Hello World");
$img->writeImage("output.png");
sorry that I couldn't find out how to set the fill color, but this is another issue you may know how to solve it.
P.S. You need to make sure you have pango installed, and imagemagick library is built with pango support (which is done for you since you are able to use command line).
I'm running into an unusual issue here. I'm simply trying to annotate an image with ImageMagick on PHP (installed via PECL), and the script times out. I've been able to narrow it down to where I annotate the image due to the fact that PHP tells me it times out at line 13 (code below):
<?
$imagick = new Imagick();
$imagick->readImage("static/image.jpg");
$draw = new ImagickDraw();
$draw->setStrokeColor("white");
$draw->setFillColor("black");
$draw->setStrokeWidth(2);
$draw->setFontSize(36);
//$draw->setFont("static/fonts/Impact.ttf");
$imagick->annotateimage($draw, 40, 40, 0, "Lorem Ipsum!");
header("Content-Type: image/jpg");
echo $imagick;
?>
At this point in time I've just copied and pasted code from a tutorial. I did have my own code but it didn't work, so I decided to copy just to see whether I'd done something wrong. Lo and behold, this doesn't work either. If I remove both of the two lines ($draw->setFont) and the annotateImage it outputs the image just fine. For some reason I can not annotate correctly.
I can verify that it does not work if I use 'Arial' as the font instead of the copy of Impact.ttf that I have.
To clarify: I'm on OS X, using XAMPP.
i have installed imageMagick and ghostscript from online and put it inside mamp but m not getting how to include them in my php code..
by googling i found a code
<?php
$pdf = 'serviceReport.pdf';
$save = 'output.jpg';
exec('convert "'.$pdf.'" -colorspace RGB -resize 800 "'.$save.'"', $output, $return_var);
?>
but m not getting the result..can anyone help with this
It is much effective to use the php extension ImageMagick offers (Imagick) instead of command line tools:
<?php
// ...
$img = new \Imagick();
$img->readimage($filedata['tmp_name']); // this can be a pdf file!
$img->setResolution(300,300);
$img->writeImage(sprintf('%1$s/%2$s.jpg', $basepath, $basename));
// ...
?>
Another alternative is to use the poppler tools instead. They offer much faster processing.
Hi I'm porting a script from a windows environment running MagickWand 0.1.8 and ImageMagick 6.2.9 where transparency worked fine with MagickRotateImage.
New environment is linux running MagickWand 1.0.8 with ImageMagick 6.5.4-7 and transparency gets lost and it shows black as the background as soon as my logo image gets rotated.
From what I've found online, seems that PixelSetColor($bg,"none") doesn't work with the newer versions hence the black. Ultimately, I need to know what to replace PixelSetColor($bg,"none") with. I just don't have a background in image creation so struggling a bit with this.
First my php runs this function which makes a local 60x60 version of 600x600 png image gotten from a url.
function makeThumb($fileContents){
GLOBAL $localImgPath1;
GLOBAL $localImgPath2;
$wand = NewMagickWand();
$lg = MagickReadImageBlob($wand,$fileContents);
$lg_w = MagickGetImageWidth($wand);
$lg_h = MagickGetImageHeight($wand);
$max = max($lg_h,$lg_w);
$scale_factor = 60/$max;
MagickResizeImage($wand,$lg_w*$scale_factor,$lg_h*$scale_factor, MW_GaussianFilter, .7);
MagickWriteImage($wand, $localImgPath1);
if($localImgPath2!="")
MagickWriteImage($wand, $localImgPath2);
$resized_w = MagickGetImageWidth($wand);
$resized_h = MagickGetImageHeight($wand);
DestroyMagickWand($wand);
}
then, I use this to read that locally written png image and rotate it:
$logo = NewMagickWand();
$bg = NewPixelWand();
PixelSetColor($bg,"none");
MagickReadImage($logo, $localImgPath1);
MagickRotateImage($logo, $bg, $r);
header('Content-Type: image/PNG');
MagickEchoImageBlob($logo);
DestroyPixelWand($bg);
DestroyMagickWand($logo);
I've tried things like adding:
$transparent = NewPixelWand("#FFFFFF");
PixelSetAlpha($transparent, 0);
//and then making the rotate call:
MagickRotateImage($logo, $transparent, $r);
Also tried adding MagickSetImageAlphaChannel($logo, MW_SetAlphaChannel); before the rotate step. Saw some posts mentioning that method but possibly that's not the correct way to use it. Not sure.
I also have the same problem in a script that draws a text string with a set font onto the image. Black immediately shows there even before rotation is applied so hoping same fix for the logo script will be useable by the font script.
Any help would be greatly appreciated. Thanks.
You've got a choice of four values for a transparent background. Try each in turn:
"none", "transparent", "#00000000", or "rgba(0, 0, 0, 0.0)"
The problem was with ImageMagick 6.5.4-7. Must have been a buggy release. Upgraded to 6.8.4-10 and above code works fine, PixelSetColor($bg,"none") works for the transparency.