【问题标题】:Outline a transparent image using imagick PHP使用 imagick PHP 勾勒出透明图像
【发布时间】:2016-02-26 13:29:11
【问题描述】:

我有一个透明背景的图像,我想用 5 像素的边框勾勒出轮廓。在 Photoshop 中,我可以通过描边来实现这一点。

我尝试过使用borderImage,但它无法勾勒出企鹅的轮廓。

$image = new Imagick();
$image->readImage('tux.png');

$image->borderImage(new ImagickPixel('red'), 5, 5); // no outline

这是图片。

这就是我想要达到的目标。

【问题讨论】:

标签: php image imagick outline


【解决方案1】:

我将从命令行开始,稍后可能会做 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 幻数,也许还有一些不必要的克隆和东西 - 我会把它留给你!

【讨论】:

  • 很好的解决方案!我一直试图在 PHP 中复制它,但无济于事。你能把它转换成PHP吗?
  • 我尝试了一些业余的 PHP - 我会让你将其提高到生产质量:-)
  • 好东西,马克!我很感激。如果需要,请随时更新。
  • 第 3 步不起作用 - 我得到一个空的输出图像:/
  • 你能把轮廓画多薄?
【解决方案2】:

enter image description here function 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]

【讨论】:

  • 你能把轮廓画多薄?
猜你喜欢
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 2014-08-12
  • 1970-01-01
  • 2014-01-25
  • 2018-03-30
相关资源
最近更新 更多