带有黑白面具的蒙版 PNG 图像
Mask PNG image with black and white mask
我有如下图片(请注意透明背景):
我也有一个black/white口罩同样大小:
我想 "crop" 这件衣服,只得到第一张图片中黑色圆圈中的部分。我尝试了很多不同的方法,但它们都不起作用或太慢:
1) ImageMagick(命令行)<== 我可以使用哪个命令来实现此目的?我试过 multiply 和 copyopacity 但它们没有用
2) WideImage 正在运行:$maskedImage = $source->applyMask($mask);
但需要超过 12 秒。
如果可能,我对 ImageMagick 解决方案感兴趣。
编辑
如果掩码小于原始图像并且原始图像很简单,则提供的解决方案可以正常工作。使用这些源图像和蒙版,结果是 "smeared":
来源:
掩码:
命令:
convert source.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png
结果(为了显示错误的白色,我添加了灰色背景而不是透明背景):
我想你想要这个:
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
您的 ImageMagick 版本似乎太旧,无法包含 "copyalpha" 组合运算符。这是获得结果的另一种方法...
convert dress.png \( circle.png -negate \) \
\( -clone 0 -transparent red +transparent red \) -insert 0 -composite result.png
读入你的主图像,然后读入你的蒙版图像并取消它,然后创建一个透明层并使用“-insert”将其移动到列表中的第一个位置。 ImageMagick 对具有三个输入图像的“-composite”的默认处理是使用第三个图像(现在是带有黑色圆圈的图像)作为 alpha 蒙版。您仍然需要“-negate”那个蒙版,或者制作一个黑白颠倒的新蒙版。
那里用来创建透明的方法canvas是读入括号内的其他图像之一,将所有红色更改为透明,然后将所有更改不红色至透明。这导致完全透明 canvas 用作复合列表中的第一张图像,即目标图像。
使用 copy_opacity 而不是 copy_alpha,它应该在 ImageMagick 6 或 ImageMagick 7 中正常工作。这对我来说很好用:
输入:
掩码:
convert dress.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png
上面使用convert的命令适用于ImageMagick 6。如果使用ImageMagick 7,请将convert改为magick。两者都对我有用。
一天结束时,我一直在使用 WideImage,虽然速度很慢,但效果很好。这是我用来屏蔽图像的 class:
<?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;
}
}
我有如下图片(请注意透明背景):
我也有一个black/white口罩同样大小:
我想 "crop" 这件衣服,只得到第一张图片中黑色圆圈中的部分。我尝试了很多不同的方法,但它们都不起作用或太慢:
1) ImageMagick(命令行)<== 我可以使用哪个命令来实现此目的?我试过 multiply 和 copyopacity 但它们没有用
2) WideImage 正在运行:$maskedImage = $source->applyMask($mask);
但需要超过 12 秒。
如果可能,我对 ImageMagick 解决方案感兴趣。
编辑
如果掩码小于原始图像并且原始图像很简单,则提供的解决方案可以正常工作。使用这些源图像和蒙版,结果是 "smeared":
来源:
掩码:
命令:
convert source.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png
结果(为了显示错误的白色,我添加了灰色背景而不是透明背景):
我想你想要这个:
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
您的 ImageMagick 版本似乎太旧,无法包含 "copyalpha" 组合运算符。这是获得结果的另一种方法...
convert dress.png \( circle.png -negate \) \
\( -clone 0 -transparent red +transparent red \) -insert 0 -composite result.png
读入你的主图像,然后读入你的蒙版图像并取消它,然后创建一个透明层并使用“-insert”将其移动到列表中的第一个位置。 ImageMagick 对具有三个输入图像的“-composite”的默认处理是使用第三个图像(现在是带有黑色圆圈的图像)作为 alpha 蒙版。您仍然需要“-negate”那个蒙版,或者制作一个黑白颠倒的新蒙版。
那里用来创建透明的方法canvas是读入括号内的其他图像之一,将所有红色更改为透明,然后将所有更改不红色至透明。这导致完全透明 canvas 用作复合列表中的第一张图像,即目标图像。
使用 copy_opacity 而不是 copy_alpha,它应该在 ImageMagick 6 或 ImageMagick 7 中正常工作。这对我来说很好用:
输入:
掩码:
convert dress.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png
上面使用convert的命令适用于ImageMagick 6。如果使用ImageMagick 7,请将convert改为magick。两者都对我有用。
一天结束时,我一直在使用 WideImage,虽然速度很慢,但效果很好。这是我用来屏蔽图像的 class:
<?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;
}
}