convert tux.png -alpha extract alpha.png
第二步 - 获取不透明区域的边缘
现在,您想要该轮廓的边缘,因此我将使用 -morphology
:
convert alpha.png -morphology edge octagon -threshold 50% edge.png
我听说一些人在PHP中使用形态学操作时遇到了困难,因此这里提供了一种不使用形态学的替代方法。基本上,它会复制alpha层,然后使用统计学方法找到每个3x3框中最亮的像素(仅在存在黑色和白色像素的3x3框边缘才会产生影响),然后将结果与原始结果进行差异以显示受影响的像素。比描述起来更容易实现!
convert alpha.png \( +clone -statistic maximum 3x3 -threshold 50% \) -compose difference -composite edge.png
对于更粗的线,请使用5x5的盒子。
我看到有一个选项-edge 5
,这样会更容易 - 我们不断学习进步!
步骤3 - 将边缘变成红色,其余透明
现在您需要将白色变为红色,将黑色变为透明:
convert edge.png -fill red -opaque white -transparent black rededge.png
第四步 - 在原图上添加红色轮廓
最后,您需要将其与原始图像合成:
convert tux.png rededge.png -composite result.png
全面实现
或者,您可以像这样一次性完成所有操作:
convert tux.png \( +clone -alpha extract -morphology edge octagon -threshold 50% -fill red -opaque white -transparent black \) -composite result.png
您可能更喜欢使用 -morphology edgeout
命令,因为它的效果比 -morphology edge
更加微妙。
PHP 版本
我的 PHP 技能 "较弱",但我已经开始学习并取得了一些进展——稍后会更新,目前看起来是这样的:
$image = new Imagick("tux.png");
$alpha = clone $image;
$alpha->separateImageChannel(Imagick::CHANNEL_ALPHA);
$alpha->negateImage(true);
$alpha->edgeImage(5);
$alpha->opaquePaintImage("white","red",65000,FALSE);
$alpha->transparentPaintImage("black",0.0,0,FALSE);
$image->compositeImage($alpha,Imagick::COMPOSITE_DEFAULT,0,0);
$image->writeImage("result.png");
看起来这基本上是有效的,但有些方面可能需要整理 - 特别是 65000
这个神奇的数字和可能存在的一些不必要的克隆等等 - 我会把这留给你来处理!
输入图像描述 函数getCharacterOutline() {
$imagick = new \Imagick(realpath("pen.png"));
$character = new \Imagick();
$character->newPseudoImage(
$imagick->getImageWidth(),
$imagick->getImageHeight(),
"canvas:white"
);
$canvas = new \Imagick();
$canvas->newPseudoImage(
$imagick->getImageWidth(),
$imagick->getImageHeight(),
"canvas:black"
);
$character->compositeimage(
$imagick,
\Imagick::COMPOSITE_COPYOPACITY,
0, 0
);
$canvas->compositeimage(
$character,
\Imagick::COMPOSITE_ATOP,
0, 0
);
$canvas->setFormat('png');
return $canvas;
}
$canvas = getCharacterOutline();
$kernel =\ImagickKernel::fromBuiltIn(\Imagick::KERNEL_OCTAGON, "3");
$canvas->morphology(\Imagick::MORPHOLOGY_EDGE, 1, $kernel);
header("Content-Type: image/png");
echo $canvas->getImageBlob();
[result][1]