我需要知道如何使用Imagick屏蔽任何方形图像。这是我到目前为止的代码,但图像没有被正确掩盖:
获取图片
$srcFile = 'filename.png';
$image = new Imagick($srcFile);
将图像裁剪为方
$d = $image->getImageGeometry();
$src_width = $d['width'];
$src_height = $d['height'];
$thumbSize = min(max($src_width, $src_height), abs($thumbSize));
if ($src_width < $src_height) {
$image->cropImage($src_width, $src_width, 0, (($src_height - $src_width)/2));
} else {
$image->cropImage($src_height, $src_height, (($src_width - $src_height)/2), 0);
}
调整图片大小
$image->thumbnailImage($thumbSize, $thumbSize, 1);
使用贝塞尔曲线形状裁剪/遮罩图像
$image->compositeImage(bezier($thumbSize, $thumbSize), Imagick::COMPOSITE_COPYOPACITY, 0, 0);
bezier函数创建一个如下所示的形状:
function bezier($width, $height) {
$fillColor = "#000";
$draw = new ImagickDraw();
用黑色填充未遮罩的部分
$fillColor = new ImagickPixel($fillColor);
$draw->setFillColor($fillColor);
$smoothPointsSet = [
[
['x' => 0.0 * $width, 'y' => 0.5 * $width],
['x' => 0.0 * $width, 'y' => 0.905 * $width],
['x' => 0.095 * $width, 'y' => 1.0 * $width],
['x' => 0.5 * $width, 'y' => 1.0 * $width]
], [
['x' => 0.5 * $width, 'y' => 1.0 * $width],
['x' => 0.905 * $width, 'y' => 1.0 * $width],
['x' => 1.0 * $width, 'y' => 0.905 * $width],
['x' => 1.0 * $width, 'y' => 0.5 * $width]
], [
['x' => 1.0 * $width, 'y' => 0.5 * $width],
['x' => 1.0 * $width, 'y' => 0.095 * $width],
['x' => 0.905 * $width, 'y' => 0.0 * $width],
['x' => 0.5 * $width, 'y' => 0.0 * $width]
], [
['x' => 0.5 * $width, 'y' => 0.0 * $width],
['x' => 0.095 * $width, 'y' => 0.0 * $width],
['x' => 0.0 * $width, 'y' => 0.095 * $width],
['x' => 0.0 * $width, 'y' => 0.5 * $width]
]
];
foreach ($smoothPointsSet as $points) {
$draw->bezier($points);
}
bezier积分不填充中间的正方形,因此请手动填充
$points = [
['x' => $width * 0.5, 'y' => 0.0],
['x' => 0.0, 'y' => $height * 0.5],
['x' => $width * 0.5, 'y' => $height],
['x' => $width, 'y' => $height * 0.5]
];
$draw->polygon($points);
将抽屉图像复制到新的透明Imagick图像
$imagick = new Imagick();
$imagick->newImage($width, $width, "none");
从这里开始,我尝试了各种属性。我没有得到任何令人满意的结果 - 图像几乎总是没有被掩盖。
#$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE);
#$imagick->setImageFormat("png");
$imagick->drawImage($draw);
#$imagick->setImageMatte(false);
return $imagick;
}
如果我能知道问题所在以及如何解决问题,我将非常高兴。我在SO上发现了各种不适合我的答案:
使用$dude->setImageMatte(1);
Using a transparent PNG as a clip mask
使用$base->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA);
How to use Imagick to merge and mask images?
不幸的是我无法解决问题。
答案 0 :(得分:0)
问题是图像存储为JPEG,因此透明部分变黑。这是我使用的代码:
$mask = bezier($thumbSize, $thumbSize);
// Copy opacity mask
if ($image->getImageMatte()) {
$image->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA);
} else {
$image->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0);
}
$image->setImageBackgroundColor(new ImagickPixel('white'));
#$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_DEACTIVATE);
$image = $image->flattenImages();
在函数贝塞尔:
$imagick = new Imagick();
$imagick->newImage($width, $width, "none");
$imagick->setImageBackgroundColor(new ImagickPixel('transparent'));
#$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE);
$imagick->setImageFormat("png");
//Render the draw commands in the ImagickDraw object
//into the image.
$imagick->drawImage($draw);
$imagick->negateImage(FALSE);
return $imagick;