Imagick: compose with mask

落花浮王杯 提交于 2019-11-27 23:16:19

问题


I try to recreate a script that uses the ImageMagick command "convert" to compose an image. But I want to do the same in PHP using Imagick (version 6.6.2-10).

The command is as follows:

convert A1.mpc A3.mpc A4.mpc -channel rgba -alpha on -virtual-pixel background -background none -define compose:args=312x26.6776 -compose displace -composite out.mpc

I found out that the parameters stand for the following:

convert  {background} {overlay} [{mask}] [-compose {method}] -composite {result}

The PHP Imagick gives me a compose method, but without a mask parameter: http://www.php.net/manual/en/imagick.compositeimage.php

I found another question and tries this (but does not result in the same image):

// load images
$a1 = new Imagick('a1.png');
$a3 = new Imagick('a3.png');
$a4 = new Imagick('a4.png');

// mask the overlay
$a1->compositeImage($a4, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA);

// compose overlay to background
$a1->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_BACKGROUND);
$a1->setImageBackgroundColor(new ImagickPixel('none'));
$a1->setOption('compose:args', '312x26.6776');
$a1->compositeImage($a3, Imagick::COMPOSITE_DISPLACE, 0, 0);

So my question is: is this the right way to compose an image using a mask? Or what's wrong here?

To help visualizing what I want to do, here are some input images:

input image a1 (background):

input image a3 (overlay):

input image a4 (mask):

What I want the result to be:

What my php code creates:

Thanks in advance! Michael


回答1:


try using compositeImage method and Imagick::COMPOSITE_COPYOPACITY




回答2:


Try this code:

// x-displacement
$a3->setImageArtifact('compose:args', "312x0");
$a1->compositeImage($a3, Imagick::COMPOSITE_DISPLACE, 0, 0);

// y-displacement
$a4->setImageArtifact('compose:args', "0x26.6776");
$a1->compositeImage($a4, Imagick::COMPOSITE_DISPLACE, 0, 0); 



回答3:


After struggling with this I finally found a way how to do it properly with PHP-Imagick.

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

$displaceMask->setImageArtifact('compose:args', '312x26.6776');
$a1->compositeImage($displaceMask, Imagick::COMPOSITE_DISPLACE, 0, 0);

Resources that I used:

  • https://github.com/mkoppanen/imagick/issues/49
  • https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=26323
  • Merging RGB channels back into a single image with ImageMagick (php)
  • https://imagemagick.org/script/command-line-options.php#combine



回答4:


I do not know if this will help, but I processed your images in ImageMagick 6.9.10.62 and 6.9.10.5 Q16 Mac OSX with the same result as shown below.

So if there is an issue, it is likely with Imagick.

What was your exact version of 6.9.10.x?

convert img.png \
\( dx.png dy.png dy.png -combine \) \
-define compose:args=312x26.6776 -compose displace -composite \
result.png


I notice that if the same image dx is combined for dy, then I get a result similar to your bad result. That might mean that either the addImage or the flattenImage or the combineImage is not working correctly in your new Imagick.

convert img.png \
\( dx.png dx.png dy.png -combine \) \
-define compose:args=312x26.6776 -compose displace -composite \
result2.png


Check your code to be sure you do not have a typo using $a3, $a3, and either $a3 or $a4 for your addImage.

For a test, try PHP

exec("convert img.png \( dx.png dy.png dy.png -combine \) -define compose:args=312x26.6776 -compose displace -composite result.png")


来源:https://stackoverflow.com/questions/13232551/imagick-compose-with-mask

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!