skip to Main Content

I had the code running to create a “cylinder” effect via ImageMagick v6.7.9 and PHP (Imagick extension v3.2.0), it’s like described in the accepted answer of my previous question: https://stackoverflow.com/a/54807019/1800172 It’s inspired by Fred’s cylinderize script: http://www.fmwconcepts.com/imagemagick/cylinderize/

After creating the X/Y-displacements ($a3/$a4) it’s combined like this:

// merge x-displacement and y-displacement into one displacement-map
$displaceMask = new Imagick();
$displaceMask->addImage($a3);
$displaceMask->addImage($a4);
$displaceMask->addImage($a4);
$displaceMask->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$displaceMask = $displaceMask->combineImages(Imagick::CHANNEL_ALL);

$displaceMask->setImageArtifact('compose:args', '1600x83.669513037752');
$image->compositeImage($displaceMask, Imagick::COMPOSITE_DISPLACE, 0, 0);
$image->trimImage(0);

Now that I updated to ImageMagick v6.9.10 and Imagick v3.4.3 this does not produce the same image anymore. I already figured out that I had to change the way how to create the displacement map, to make it look the same as before:

// merge x-displacement and y-displacement into one displacement-map
$displaceMask = new Imagick();
$displaceMask->newImage($a3->getImageWidth(), $a3->getImageHeight(), new ImagickPixel('white'));
$displaceMask->setImageFormat('png');
$displaceMask->setImageColorspace(Imagick::COLORSPACE_RGB);

$displaceMask->compositeImage($a3, imagick::COMPOSITE_COPYRED, 0, 0);
$displaceMask->compositeImage($a4, imagick::COMPOSITE_COPYGREEN, 0, 0);
$displaceMask->compositeImage($a4, imagick::COMPOSITE_COPYBLUE, 0, 0);

But if I now apply the “composite” function with “displace” operator, the result looks not the same as with the old version:

$displaceMask->setImageArtifact('compose:args', '1600x83.669513037752');
$image->compositeImage($displaceMask, Imagick::COMPOSITE_DISPLACE, 0, 0);
$image->trimImage(0);

Input image:
input image

Displacement map:
displacement map

Expected resulting image (like before version update):
expected result

Resulting image (i.e. after version update):
enter image description here

My guess is that anything changed in Imagick and/or ImageMagick implementation, or in it’s (default) configuration. Anyone who can point me to the solution?

Thanks in advance!

Edit: I updated the input image, it was not the one that I use as the input of the displacement.

Edit2: I tried to apply the displacement via ImageMagick directly instead of using Imagick, and there it seems to work (ignoring the fact that the resulting image is somehow pixelated, so it’s not usable as a workaround so far):

convert input.png ( a3.png a4.png a4.png -combine ) -channel rgba -alpha on -virtual-pixel transparent -background none -define compose:args=1600x83.669513037752 -compose displace -composite result.png

–> Might be a problem/bug/change in Imagick itself?

2

Answers


  1. Chosen as BEST ANSWER

    I think the problem was a change within ImageMagick and/or the Imagick PHP-extension between the versions that I used. I found this issue in the changelog of ImageMagick: https://github.com/ImageMagick/ImageMagick/issues/597 And one step further here is the actual change they did some time ago: https://github.com/ImageMagick/ImageMagick/commit/87be42439e1df8c51e7af5ea5d6591a8af499cf2

    --> to solve the issue, I had to set the compose arguments not on the displacement map, but instead on the source image. Then It was working fine again, even without the jagged lines (I had them as well when I tried it via the command line).

    So instead of

    $displaceMask->setImageArtifact('compose:args', '1600x83.669513037752');
    $image->compositeImage($displaceMask, Imagick::COMPOSITE_DISPLACE, 0, 0);
    

    I had to do it like this:

    $image->setImageArtifact('compose:args', '1600x83.669513037752');
    $image->compositeImage($displaceMask, Imagick::COMPOSITE_DISPLACE, 0, 0);
    

  2. I cannot reproduce your results with ImageMagick 6.9.10.62 nor 6.7.8.9.

    Both are extremely jagged for the border of the center circle. But the straight lines are not jagged, which is puzzling. You need to download the images and view at full resolution to see how jagged they are.

    How did you create your displacement map? I think that is the source of your issue — It is too coarse, i.e. not smooth enough. It is 8-bits per channel per pixel and needs to be saved as 16-bits or even higher for such a large image.

    convert img.png displace.png 
    -channel rgba -alpha on -virtual-pixel transparent -background none 
    -define compose:args=1600x83 -compose displace -composite result.png
    

    Result from IM 6.9.10.62:

    enter image description here

    Result from IM 6.7.8.9:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search