Error with imagemagick overlay (watermark)
joncup - June 20, 2008 - 20:57
| Project: | Imagecache Actions |
| Version: | 6.x-1.4 |
| Component: | Miscellaneous |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Jump to:
Description
I set up an overlay, Overlay: file image to canvas (watermark) lone_pine_logo_1.jpg x:center, y:center alpha:75%
I got the same error with a text overlay.
call_user_func_array() [<a href='function.call-user-func-array'>function.call-user-func-array</a>]: First argument is expected to be a valid callback, 'imageapi_imagemagick_image_overlay' was given in /homepages/9/d229203311/htdocs/website.com/sites/all/modules/imagecache_actions/imagecache_canvasactions.module on line 113.
#1
Imagemagic is not fully supported for a few custom actions that were added only for this utility :-(
I don't have imagemagick available for testing and development.
We can probably update the thing to give a better error - for a start.
I also don't imagine it would be too hard to port the imageapi_image_overlay() function to imagemagick ... but I've never coded for imagemagick is all. Any imagemagick fans want to try?
#2
thanks for the speedy reply, i just switched to gd, works great, im happy with gd, thanks again
#3
I also hit this bug and had to switch to GD, however that uncovered another problem. My server runs Ubuntu, but because PHP bundles its own forked version of the GD libraries, and Debian being the anal retentive package nazis that they are, the PHP package that Ubuntu syncs from Debian is built without the bundled GD library. This means we need to install the official libs which are missing several features such as Image Filtering and Image Rotation.
Fortunately the module has a workaround for them, but I'd really like to see an ImageMagick version of overlay so I can ditch GD again.
In the mean time, please fix that error message so it's meaningful.
#4
IMHO, ImageActions overlaying GD algorithm is the nice training exercise in PHP coding, having no practical value. Applying 4 small round corners to a 600x400 image takes about 3-4 seconds on my Ubuntu 8.04 with AMD 64 4000+.
I added ImageMagick overlaying support to [backwarded] ImageAPI [which uses 'convert' instead of right API calls of IMagick PHP module] and the same task completes in 100-150ms.
I haven't tested my modifications enough and don't like them. I had to edit imageapi_imagemagick_convert() function so I can't guarantee it will work in other cases. Its too simple to act like an full functioning interface to IM and can be used exactly for 4 actions it does atm: desature, crop, resize, rotate and nothing more.
This is my mod of imagemagick_imageapi.module:
<?php
function _imageapi_imagemagick_convert($source, $dest, $args) {
$args['quality'] = '-quality '. escapeshellarg(variable_get('imageapi_imagemagick_quality', 75));
$source_in_beginning = false;
foreach ($args as $k => $arg) {
if (strpos($arg, $source) === 0) {
$args[$k] = substr($arg, strlen($source));
$source_in_beginning = true;
}
}
if ($source_in_beginning)
$args[0] = escapeshellarg($source).' '.$args[0];
else
$args[] = escapeshellarg($source);
$args[] = escapeshellarg($dest);
$command = implode(' ', $args);
if (0 != _imageapi_imagemagick_convert_exec($command, $output, $errors)) {
return false;
}
return file_exists($dest);
}
?>
And this is dirty imageapi_imagemagick_image_overlay() implementation in imagecache_canvasactions.module:
<?phpfunction imageapi_imagemagick_image_overlay(&$image, $overlay, $x, $y, $alpha) {
static $source_is_set = false;
switch ($x) {
case 'left': $x = 'West'; break;
case 'right': $x = 'East'; break;
}
switch ($y) {
case 'top': $y = 'North'; break;
case 'bottom': $y = 'South'; break;
}
$image->ops[] .= ($source_is_set ? '' : $image->source.' ').$overlay->source.' -gravity '.$y.$x.' -composite ';
$source_is_set = true;
return true;
}
?>
This is only valid for x=left,right and y=top,bottom. Nice parsing of X and Y is yet to be done.
#5
it doesn't do the transformation, and doesn't log the error.
here is what my $image->ops looks like, in imageapi_imagemagick_image_overlay():
Array(
[0] => -resize 455x342!
[1] => -crop 288x342+84+0!
[2] => sites/default/files/images/sideimage/4th_floor_detail.jpg sites/default/files/gallery/gallerymask.png -gravity NorthWest -composite
)
Also, as a sidenote, I set the function to look like this (defaults to North&West, if it's a bad value)
<?phpfunction imageapi_imagemagick_image_overlay(&$image, $overlay, $x, $y, $alpha) {
static $source_is_set = false;
switch ($x) {
case 'right': $x = 'East'; break;
default: $x='West';
}
switch ($y) {
case 'bottom': $y = 'South'; break;
default: $y = 'North';
}
$image->ops[] .= ($source_is_set ? '' : $image->source.' ').$overlay->source.' -gravity '.$y.$x.' -composite ';
$source_is_set = true;
return true;
}
?>
Upon closer inspection, it's making double-copies of the files, named like this: filename-0.jpg, filename-1.jpg. 0 appears to apply the overlay (but be scaled wrong, in some cases) and 1 is just a copy of the original.
#6
would be very interested in seeing this work completed.
#7
I pasted that code, untested into the current dev release last week.
Anyone who uses imagemagick can give some feedback. I can't.
The gd algorithm has the practical value of actually working although we know it's inefficient. This is due to a limitation on the built-in gd library that was doing bad things with transparencies using the available image copy functions in whatever update was available with PHP last year.
Something that works is better than something that doesn't, so even if it takes 3 seconds out of your day, it only has to happen once per image.
Some hosts don't allow commandline executions at all, so imagemagick isn't always the only answer, although anyone is welcome to keep working on it. All our extra actions can and should be ported to imageMagick - by someone who wants it and can do it.
#8
Hi dman
I've just tested the above suggested two functions and they work perfectly. (Picked #5 by konsumer)
However keep in mind that it only works after patching imageapis _imageapi_imagemagick_convert as described.
Imagemagick ist really a big improvement to the gd thing if available...
#9
I agree completely with dman, above. I use gd on any site that I have the option. It's slower, but it actually works.
#10
There MAY be a combination of directives that get GD imagecopymerge to do the right thing with full alpha transparency without jaggies. I was unable to get consistent results with it - eg on already partially transparent PNGs, and hence used the borrowed algorithm where it was clear what was happening.
If anyone has the right magic words to make GD faster and use the native processes, please suggest what is needed.
#11
Has this issue been resolved?
I much prefer to use imagemagick because of it's speed, and the fact that GD is a resource hog and I am on a shared server. When I check my status page while using GD I get:
Can someone help explain how I can apply the patch in #5?
#12
#13
the above code is available in the -dev release. Works.
However it does not support alpha transparency. Fixes are needed from someone that knows imagemagick or thinks it's worthy.