I have the following image (please note the transparent background):
I also have a black/white mask of the same size:
I would like to "crop" the dress and get just the portion of the first image contained in the black circle. I tried many different methods but they didn't work or are too slow:
1) ImageMagick (command line) <== which command can I use to achieve this? I tried multiply and copyopacity but they didn't work
2) WideImage is working: $maskedImage = $source->applyMask($mask);
but it takes more than 12 seconds.
I am interested in a ImageMagick solution if possible.
EDIT
The provided solutions work fine if the mask is smaller than the original image and if the original image is simple. With these source image and mask the result is "smeared":
Source:
Mask:
Command:
convert source.png \( mask.png -negate \) -alpha off -compose copy_opacity -composite result.png
Result (I added a grey background instead of the transparent one in order to show the wrong white):
At the end of the day I kept using WideImage which is quite slow but works well. This is the class I use to mask images:
<?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;
}
}