Imagemagick Composite Overwriting File - php

Good day. I am new to Imagemagick, and I just wanna ask what's wrong with this code
$cmd_for_wm = "composite -gravity southeast watermark.png image.jpg image.jpg;";
exec($cmd_for_wm);
When I run it in the terminal, it is working well, but when I incorporated it in PHP, it doesn't work. Why?
Thanks for you in advance :) Cheers

I've tried your example and it does "die" silently.
This, on the other hand seems to work:
$cmd_for_wm = "composite -gravity southeast watermark.png image.jpg image.jpg;";
passthru($cmd_for_wm);
Very curious indeed. Since the main difference between exec and passthru is the output handling. The later is used for binary data.
My take on this is that passthru correctly allows composite to output the processed image (which is binary data) into the specified file.
For a detailed explanation, please see PHP - exec() vs system() vs passthru()

Related

Combining 2 GraphicsMagick commands into 1 command, like in ImageMagick

I was using ImageMagick to create a new resized image with watermark, with this single command (in PHP):
exec("convert -filter Lanczos {$original_image} -thumbnail {$max_width}x{$max_height} -quality 90 {$watermark} -gravity center -unsharp 2x0.5+0.7+0 -composite {$cached}");
Now I switched to GM and am looking for a way to run 1 command to do the same task. The only way I found was to split it to 2 separate commands:
//create the resized image
exec("gm convert -filter Lanczos {$original_image} -thumbnail {$max_width}x{$max_height} -quality 90 -unsharp 2x0.5+0.7+0 {$cached}");
//apply the watermark and recreate the watermarked image, overwriting the previously resized image
exec("gm composite -quality 90 -dissolve 100 -gravity center {$watermark} {$cached} {$cached}");
Is there a way to combine them into 1 single command and by that maybe also reduce resources & drive usage?
I have received the following reply on this from Bob Friesenhahn, GraphicsMagick Maintainer:
You did not say what version of GraphicsMagick you are using. Modern
versions support a '-compose' option which may be put on the command
line after the input file name to remember the composition algorithm
to use. This composition algorithm is then used if the -mosaic or
-extent operators are used to do a composition. You can also use a
-page option after the input file name to locate the image when it
is composited with prior images in the list. Due to a weakness in
GM's convert command processing, the -mosaic or -extent operators must
be the last command prior to saving the output file. I believe that
ImageMagick's -composite must be a version of -mosaic which adds more
features (e.g. -mosaic might not support gravity but -composite does).
It seems like GraphicsMagick should implement something completely
compatible with ImageMagick's -composite.
Regardless, there is an effective workaround available if you need to
use your existing GM commands.
If you have a modern GraphicsMagick which supports 'gm batch', then
you can use the 'mpr' coder ("Magick Persistent Registry") to remember
intermediate images between commands and you can easily adapt your two
commands to execute with full efficiency using the existing command
lines. This Unix shell example should give you some ideas:
{
echo convert seaworld.jpg mpr:temporary
echo convert mpr:temporary crap.jpg
} | gm batch -prompt off -echo on
convert seaworld.jpg mpr:temporary
convert mpr:temporary crap.jpg
Notice that the output of the first command was saved (as an image
handle as natively used within GraphicsMagick) into 'mpr:temporary'
and then the second command took input from 'mpr:temporary' and wrote
the final output file. You can use arbitrary string arguments to
'mpr:' so you can have several images "in flight".
With this approach you can use 'gm convert' and 'gm composite' in the
same batch command.
I am not sure how one would best access this batch facility from PHP
but if PHP can stream commands to it from a pipe, then it can run for
quite a long time as a co-process to PHP and save considerable compute
time and overhead.

PHP imagick detect transparency

I want to be able to detect whether an image is transparent or not using the Imagick PHP extension.
So far, the only luck I've been having is to run the exec() / some other command, and use the ImageMagick command line tool to achieve this. Here's what I mean:
exec("identify -verbose example_transparent_image.png | grep \"Alpha\"", $output);
$is_transparent = !empty($output) ? true : false;
The logic is simple. Do a verbose check on the image in question: if the output contains any alpha information, that means it uses transparency.
It seems that the PHP imagick extension should have this as one of its commands, but the lack of documentation is killing me. It seems silly to have to run this kind of check each time.
Ahhh, solved (I think). Imagick has a function getImageAlphaChannel() which returns true if it contains any alpha information and false if it doesn't.
Make sure you have ImageMagick 6.4.0 or newer.
http://www.php.net/manual/en/function.imagick-getimagealphachannel.php
Maybe this
http://ru.php.net/manual/en/function.imagick-identifyimage.php
What's about this?
substr((new Imagick($FILE))->identifyImage()['type'], 0, -5) == 'Alpha'
look at the documentation of identifyImage. You will notice the missing documentation of the functions output. It's just a parsed version of
identify -verbose $FILE (from the imagick package)
where type identifies the image's type (compare source).
You can see that imagick returns the value from some MagickTypeOptions array which is defined here. This array contains an -Alpha and -Matte version for every image type if it's color palette contains alpha.
Theoretically you could save an image with such palette without using it, but every decent programm should swith to the non-alpha version in this case. But false positives are possible but should be rare.
Also I don't check for the -Matte image types because in the array is defined in a way that for every image type constant there are two entries with different names (-Alpha and -Matte), but as -Alpha comes first this name will be returned for that image type.

How to create kaleidoscope images like default avatars here at SO?

How can I create kaleidoscope images like default avatars here at SO, using PHP?
I'm pretty sure the default generated images are actually generated by gravatar, more about that here: http://en.gravatar.com/site/implement/images/
According to them, they use the "identicon" which is actually based on the email.
http://scott.sherrillmix.com/blog/blogger/wp_identicon/
You can take a look at that code and see how it's generated :)
You can use Imagemagick binding to php.
Here are some distortion functions: http://www.imagemagick.org/Usage/distorts/
And here is kaleidoscope script: http://www.fmwconcepts.com/imagemagick/kaleidoscope/index.php
You can combine distortions and kaleidoscope to get nice pictures.
E.g. something like this (bash, not php):
$ mkkal='dx=i-50; dy=j-50; rad=hypot(dx,dy); tt=mod((atan2(dy,dx)+6.28319+0)*5/(6.28319),1.0); ang=2*(tt<0.5?tt:1-tt); u.p{50+rad*cos(ang),50+rad*sin(ang)}'
$ convert -size 100x100 pattern:checkerboard -distort Barrel '-0.2 -3.0 0.2 1.3' -fx "$mkkal" tile.png
$ display tile.png
Try different args to Barrel or different distortion methods to get more interesting results.
They are created by gravatar.com
Examplse: http://www.gravatar.com/avatar/78fg67b5c2c25634fgadd727f6b08?s=32&d=identicon&r=PG

ImageMagick: What is this convert-command doing?

I'm trying to port a PHP script to Ruby and until now I only used ImageMagick to convert from one file-format to another. Meaning: Yes, I'm an ImageMagick newbie. ;-)
Somewhere inside the PHP script the following code is executed:
$output = array();
$returnValue = 0;
$cmd = 'convert '.$pngFile->path.' -resize 1x1 -alpha on -channel o -format "%[fx:u.a]" info:'
exec($cmd, $output, $returnValue);
Using the ImageMagick documentation for convert I identified the following options:
-resize 1x1 Resize to 1x1 pixels (right?)
-alpha on Activate alpha-channel
-channel o Apply options to the opacity image-channel
My questions:
What does -format "%[fx:u.a]" exactly do? I know that u is a symbol for first image in sequence and a one for alpha. But I don't get what the whole expression really does.
What does info: stand for?
What does this convert-command exactly do?
Thank you very much for your kind help.
Please note: The accepted answer on the following question has a very good answer to this question:
Understanding ImageMagick's convert and translating to Ruby RMagick
Seems like it is computing the average opacity. The info format is a dummy image format that will instruct convert to output image information to stdout (: means stdout) in the format %[fx:u.a]. Resizing to 1x1 is probably a way of averaging.

PHP system returns 4

I want to convert a pdf file to an image with PHP, but i can't get the command worked. PHP returns a 4. I don't have any kind of idea what that can be.
I am using the next code:
$tmp = system("convert -version", $value);
var_dump($value);
Someone an idea?
try
exec("convert -version 2>&1", $out, $ret);
print_r($out);
it should tell you what's wrong
It looks like the -version flag is telling the convert software (looks like imagemagick) to respond with the major version number of that software. It looks like it is working correctly. You probably need to pass it the right flags to operate properly. I suggest reading the documentation to see what flags are required to convert PDFs.
try using some of the other system functions in PHP to get more detailed output.
exec("convert -version", $output, $value);
print_r($output);
The exec function above will give you all the output from the command in the $output parameter, as an array.
The return status (which will be held in the $value parameter in the exec call above or the system call in your original code) gives you the return value of the executed shell command.
In general, this will be zero for success, with non-zero integer return values indicating different kinds of error. So it appears there's something wrong with the command as you have it (possibly -version is not recognised: often you need a double hyphen before long-hand command-line options).
Incidentally, you may also find that the passthru function is more suited to your needs. If your convert program generates binary image data corresponding to the converted PDF, you can use passthru to send that image data directly to the browser (after setting the appropriate headers of course)
err... aren't you vardumping the wrong result? (I would var dump $tmp, not $value.)
I think the code should read:
$tmp = system("convert -version", $value);
var_dump($tmp);

Categories