我将从命令行开始,稍后可能会做 PHP,或者让你解决这个问题...
第 1 步 - 提取透明度
如您所见,-border 勾勒出 整个 图像,但您实际上只想勾勒出 不透明 区域,因此您需要使用透明度,或者阿尔法层。让我们先提取它:
convert tux.png -alpha extract alpha.png
第 2 步 - 获取不透明区域的边缘
现在,您想要轮廓的边缘,所以我将使用 -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
第 4 步 - 在原始轮廓上合成红色轮廓
最后,你想把它合成到你的原版上:
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 edge,您可能更喜欢-morphology edgeout 的微妙效果。
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 幻数,也许还有一些不必要的克隆和东西 - 我会把它留给你!