Posted by joncup on June 20, 2008 at 8:57pm
Jump to:
| Project: | ImageCache Actions |
| Version: | 6.x-2.x-dev |
| Component: | Miscellaneous |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed (fixed) |
Issue Summary
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.
Comments
#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.
#14
Alpha Transparency is kind of the killer feature of watermarks. Anyone know how much of a bounty it might take to get this done?
a_c_m
#15
I couldn't find the code above in the 5.x dev release so I assume its not in there. Adding it works perfectly.
Opacity works fine if your watermark image is alpha-transparent already. It just ignores the imagecache preset opacity value and uses the alpha-channel from the watermark.
But if its not and you want to use the drupal opacity setting from the imagecache preset, it looks like you can use IM's -dissolve operator to do it:
http://www.imagemagick.org/Usage/compose/#dissolve
It accepts a number from 0-100 which makes it easy to use the imagecache opacity preset. However you need to use the 'composite' binary rather than 'convert' to do it.
#16
OK, well it should do that to come into line with GD which uses both.
Looks like this could be patched in OK. Imagemagick commandline pipeline hurts my head though. Example?
#17
So does the dev version supports Imagemagick for overlays now? Great module by the way hope someone is able to add full support for IM soon.
#18
Example is on the page I linked above. Looks like you may not have to use 'composite' as it provides a 'convert' example.
composite -dissolve {percent} overlay bgnd result
composite -dissolve {src_percent}x{dst_percent} overlay bgnd result
convert bgnd overlay -compose dissolve \
-set "option:compose:args" {src_percent},{dst_percent} \
-composite result
#19
subscribe
#20
I had much pain, took me all weekend,
but 6.x-2.x-dev now has imagemagick overlay support.
None of the methods listed in the docs worked for me and alpha transparency. Nor a dozen other attempts. Eventually I've got it with code that goes like:
convert 'sites/all/modules/imagecache_actions/tests/sample.jpg' \( 'misc/druplicon.png' -channel Opacity -evaluate Multiply 0.5 \) -geometry +132+60 -composite -quality '75' 'sites/images.drupal6-test.gadget/files/imagecache/testsuite/watermark_50-imagemagick.jpg'- what happens there is that I apply the alpha to the overlay image in a pre-subroutine, THEN merge the results.
All the other documented methods just failed for me.
#21
Automatically closed -- issue fixed for 2 weeks with no activity.