Imagick - 带图像蒙版的柔和多边形边缘

时间:2015-12-01 09:59:15

标签: php mask imagick

如何使用 setImageClipMask

绘制具有平滑边缘的图像

我的代码产生如下:

enter image description here

具有尖锐的锯齿状边缘,其中夹子掩模的边缘是。

我正在使用的代码:

// Draw clip mask
$clipMask = new \Imagick();
$clipMask->newPseudoImage($width, $height, "canvas:white");
$draw = new \ImagickDraw();
$draw->setFillColor(new ImagickPixel('black'));
$draw->polygon($myCoordinates);
$clipMask->drawImage($draw);

// Set mask
$img_main->setImageClipMask($clipMask);

// Draw image
$img_main->compositeImage($myImage, Imagick::COMPOSITE_DEFAULT, $x, $y);

1 个答案:

答案 0 :(得分:0)

tl:dr不使用蒙版而是使用渐变。

面具是二元选择;像素要么通过,要么没有,并且设计得有锋利的边缘。

渐变(不必是线性的)允许平滑地应用效果。下面的代码生成一个渐变,然后用它来平滑地在两个图像之间进行混合。

渐变生成: Gradient

输出图片: output image

<?php


$background = new \Imagick(realpath('./Skyline_400.jpg'));
$overlay = new \Imagick(realpath('./background.jpg'));

$overlay->scaleimage(
    $background->getImageWidth(),
    $background->getImageHeight()
);

$gradient = createGradient($background);

//If you need to see the gradient for debugging.
$gradient->setImageFormat("png");
$gradient->writeImage("./gradient.png");

$gradient2 = clone $gradient;
//The overlay needs to have the gradient reversed
$gradient2->negateimage(false);
$gradient2->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
$background->compositeImage($gradient2, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);

$gradient->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
$overlay->compositeimage($gradient, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);

//Create a new canvas to render everything in to.
$canvas = new \Imagick();
$canvas->newImage($gradient->getImageWidth(), $gradient->getImageHeight(), new \ImagickPixel('black'));

//Blend background into canvas
$canvas->compositeimage($background, \Imagick::COMPOSITE_BLEND, 0, 0);

//Blend overlay into canvas
$canvas->compositeimage($overlay, \Imagick::COMPOSITE_BLEND, 0, 0);

//Output the final image
$canvas->setImageFormat('png');
$canvas->writeImage("./output_test.png");



// Create a gradient/mask to allow images to be blended smoothly.
function createGradient(\Imagick $background)
{
    $myCoordinates = [
        ['x' => 20, 'y' => 20,],
        ['x' => 360, 'y' => 20,],
        ['x' => 350, 'y' => 350,],
        ['x' => 25, 'y' => 350,],
    ];

    $backgroundMask = new \Imagick();
    $backgroundMask->newPseudoImage(
        $background->getImageWidth(), 
        $background->getImageHeight(),
        'canvas:white'
    );

    $draw = new \ImagickDraw();
    $draw->setFillColor(new ImagickPixel('black'));
    $draw->polygon($myCoordinates);
    $backgroundMask->setImageFormat('png');
    $backgroundMask->drawImage($draw);

    // Blur the edges to make the transition between black and white 
    // be smooth
    $backgroundMask->blurImage(2, 0.5);

    return $backgroundMask;
}