Как я могу нарисовать изображение с гладкими краями, используя 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);
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;
}
Других решений пока нет …