Imagick — мягкие полигональные края с маской изображения

Как я могу нарисовать изображение с гладкими краями, используя setImageClipMask?

Мой код выглядит так:

введите описание изображения здесь

который имеет острые неровные края, где находится край маски клипа.

Код, который я использую:

// 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

Решение

tl: dr не используйте маски вместо градиента

Маски — это бинарный выбор; пиксель либо проходит, либо не проходит и имеет острые края.

Градиенты (которые не обязательно должны быть линейными) позволяют плавно применять эффекты. Код ниже генерирует градиент, а затем использует его для плавного смешивания двух изображений.

Градиент генерируется:
градиент

Выходное изображение:
выходное изображение

<?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;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]