1

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

在此处输入图像描述

我也有一个相同尺寸的黑色/白色面具:

在此处输入图像描述

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

1)ImageMagick(命令行)<==我可以使用哪个命令来实现这一点?我尝试了乘法和复制不透明,但它们没有用

2) WideImage 工作:$maskedImage = $source->applyMask($mask);但需要超过 12 秒。

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

编辑

如果掩码小于原始图像并且原始图像很简单,则提供的解决方案可以正常工作。使用这些源图像和蒙版,结果是“涂抹”的:

资源:

在此处输入图像描述

面具:

在此处输入图像描述

命令:

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

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

在此处输入图像描述

4

4 回答 4

0

我想你想要这个:

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

在此处输入图像描述

或者,如果您不喜欢括号,请先加载蒙版并整理您的 alpha 通道,然后加载连衣裙,然后+swap是合成前的顺序:

magick mask.png -alpha off -negate dress.png +swap  -compose copyalpha -composite result.png
于 2020-01-27T16:40:37.770 回答
0

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

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

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

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

于 2020-01-27T17:44:44.090 回答
0

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

输入:

在此处输入图像描述

面具:

在此处输入图像描述

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


在此处输入图像描述

上面使用 convert 的命令适用于 ImageMagick 6。如果使用 ImageMagick 7,请将 convert 更改为 magick。两者都为我工作。

于 2020-01-27T17:54:27.597 回答
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;
    }
}
于 2020-03-04T08:43:57.867 回答