带有黑白蒙版的蒙版PNG图像

时间:2020-01-27 16:28:58

标签: php imagemagick wideimage

我有以下图片(请注意透明背景):

enter image description here

我也有相同尺寸的黑白面具

enter image description here

我想“裁剪”衣服,只得到黑色圆圈中包含的第一张图像的一部分。我尝试了许多不同的方法,但是它们没有用或太慢:

1)ImageMagick(命令行)<==我可以使用哪个命令来实现?我尝试了乘法和复制透明度,但是它们不起作用

2)WideImage正在运行:$maskedImage = $source->applyMask($mask);,但耗时超过12秒。

如果可能的话,我对ImageMagick解决方案感兴趣。

编辑

如果遮罩小于原始图像并且原始图像简单,则提供的解决方案效果很好。使用这些源图像和蒙版,结果将被“抹上”:

来源:

enter image description here

面具:

enter image description here

命令:

convert source.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png

结果(我添加了灰色背景而不是透明背景,以显示错误的白色):

enter image description here

4 个答案:

答案 0 :(得分:0)

我想你想要这个:

magick dress.png \( mask.png -alpha off -negate \) -compose copyalpha -composite result.png

enter image description here

或者,如果您不喜欢括号,请先加载蒙版并整理您的Alpha通道,然后加载连衣裙,然后依次+swap,然后进行合成:

magick mask.png -alpha off -negate dress.png +swap  -compose copyalpha -composite result.png

答案 1 :(得分:0)

您的ImageMagick版本似乎太旧,无法包含“ copyalpha”组合运算符。这是获得结果的另一种方法...

convert dress.png \( circle.png -negate \) \
   \( -clone 0 -transparent red +transparent red \) -insert 0 -composite result.png

这将读取您的主图像,然后读取您的蒙版图像并将其取反,然后创建一个透明层,并使用“ -insert”将其移动到列表中的第一个位置。 ImageMagick对带有三个输入图像的“ -composite”的默认处理方式是使用第三个图像(现在是带有黑圈的图像)作为alpha蒙版。您仍然必须“否定”该蒙版,或者制作一个黑白颠倒的新蒙版。

用于创建透明画布的方法是读取括号内的其他图像之一,将所有红色更改为透明,然后将所有 not 更改为透明。这样就形成了一个完全透明的画布,可以用作合成列表中的第一张图像,即目标图像。

答案 2 :(得分:0)

使用copy_opacity而不是copy_alpha可以在ImageMagick 6或ImageMagick 7中正常工作。这对我来说很好:

输入:

enter image description here

面具:

enter image description here

convert dress.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png


enter image description here

以上使用convert的命令用于ImageMagick6。如果使用ImageMagick 7,则将convert更改为magick。两者都对我有用。

答案 3 :(得分:0)

最后,我继续使用WideImage,它虽然速度很慢,但是效果很好。这是我用来遮罩图像的类:

<?php

namespace AppBundle\Service\Import;

use WideImage\WideImage;

class ImageMasker
{
    /**
     * @var string
     */
    private $tempDirectory;

    public function __construct(string $tempDirectory)
    {
        $this->tempDirectory = $tempDirectory;
    }

    /**
     * @param string $sourcePath
     * @param string $maskPath
     */
    public function mask($sourcePath, $maskPath)
    {
        $source = WideImage::load($sourcePath);
        $mask   = WideImage::load($maskPath);

        $tempFilename = uniqid().'.png';
        $tempPath     = rtrim($this->tempDirectory, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$tempFilename;

        // applies the mask and saves the file
        $maskedImage = $source->applyMask($mask);
        $maskedImage->saveToFile($tempPath);

        return $tempPath;
    }
}