问题
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:
Displacement map:
Expected resulting image (like before version update):
Resulting image (i.e. after version update):
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?
回答1:
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:
Result from IM 6.7.8.9:
来源:https://stackoverflow.com/questions/57722353/apply-displacement-map-via-imagick-after-version-update