【问题标题】:Merging RGB channels back into a single image with ImageMagick (php)使用 ImageMagick (php) 将 RGB 通道合并回单个图像
【发布时间】:2012-05-31 16:17:53
【问题描述】:

所以我有一个使用 ImageMagick 和 php 的情况,我需要分别处理每个 RGB 通道,然后将它们重新合并到最终图像中。所以在我下面的代码中,$red、$green 和 $blue 是通道(作为灰度图像)。以下代码是我尝试过的(以及一些变体),但每次我最终得到的图像只有青色、洋红色或黄色显示。在这种情况下,生成的图像是青色的。

$im->removeImage();
$im->addImage($red);
$im->addImage($green);
$im->addImage($blue);
$img = $im->combineImages(self::CHANNEL_ALL);

$im->removeImage();
$im->removeImage();
$im->removeImage();
$im->addImage($img);

我认为我的部分问题是 PHP 文档没有详细说明如何使用 combineImages,而且目前我找不到任何示例。因此,我很可能错误地使用了该特定方法,并且我怀疑这与我如何在单个 Imagick 对象中组合图像开始有关。

编辑

这个问题最终归结为:如何仅使用 php 重新创建以下脚本?

convert tmp_r.png tmp_g.png tmp_b.png -combine tmp_rgb.png

【问题讨论】:

  • 我整晚都在尝试这个工作,但我总是得到一个红色或灰色的图像。几个小时后,我开始认为 addImage 是错误的,因为这看起来像是 gif 动画。我在 Imagemagick 论坛上发现了一篇建议改为合成的帖子。我无法理解 Imagick 的工作原理,因为文档完全无用且具有误导性。
  • 100% 同意文档......
  • 你在哪里找到那个帖子?
  • 没有太多信息,它在论坛的 rmagick 部分:imagemagick.org/discourse-server/… 我整个周末都在尝试创建一个所有 Imagick 操作员的示例以放在我的网站上,但我现在卡在没有很好文档的那些!
  • 您是否有任何特殊原因强迫自己使用 PHP Imagick 扩展而不是仅仅使用 shell 命令?

标签: php image-processing imagemagick


【解决方案1】:

[编辑] 我不得不承认,进一步查看文档,我不确定常量 CHANNEL_ALL 的作用。他们确实声明您可以通过逻辑或将它们连接在一起来连接通道。你可以试试:

$im->combineImages(imagick::CHANNEL_RED | imagick::CHANNEL_GREEN | imagick::CHANNEL_BLUE);

[原创] 我一直在研究这个 API,老实说,我认为您正在寻找的是 convert 函数,而不是 combine 函数。

查看下面提供的链接并专门单击“组合 RGB 通道图像” http://www.imagemagick.org/Usage/color_basics/

试试吧,如果您需要进一步的帮助,请发表评论:-)

【讨论】:

  • convert 是 image magick 提供的在命令行使用的程序。 -combine 是我试图复制的 convert 的特定功能。
  • 这就是我使用 EDIT 编辑帖子的原因。尝试在您已经拨打的电话中使用三个颜色通道的串联而不是 CHANNEL_ALL !!!
  • 抱歉,您的回答有点混乱,我对您首先提出的建议感到困惑。但是,是的,我也尝试过,结果相同。
  • 顺便说一句,我相信 self::CHANNEL_ALL 为us2.php.net/manual/en/imagick.constants.php 列出的所有通道设置了标志,而 ORing 显然只为 RGB 通道设置了它。 ALL 的 dec 值为 -1(二进制全为 1),ORing RGB 得到 7(即 0b111)。我认为 ORing 可能更可取,因为在我的情况下,大多数渠道都没有代表。无论哪种方式,它都表现出相同的行为。
  • 是的,但所有可能都包括 CMYK,这就是您看到 CYAN 的原因。您是否只是出于好奇查看了 $red、$green 和 $blue 图像的 getColorspace 例程的输出?您还确定“self”在那个时刻指的是什么(要知道 self::CHANNEL_ALL 真的会给您想要的)?
【解决方案2】:

所以我想我已经想出了如何让它发挥作用。缺少的部分是对 flattenImages() 的调用。我不确定为什么会这样,但这似乎是我想要的。这是代码(请记住,$this 是在扩展 Imagick 的类的成员方法的上下文中):

$this->removeImage(); // gets rid of the old, unprocessed image
$rgb = clone $this;

$rgb->addImage($red);
$rgb->addImage($green);
$rgb->addImage($blue);
$rgb->flattenImages(); // this is what was missing above

$rgb = $rgb->combineImages(self::CHANNEL_ALL);

$this->addImage($rgb);

谁能评论为什么会这样?我希望 flattenImages() 将三个图像合并为一个并破坏一些信息,但它似乎实际上告诉 ImageMagick 将所有包含的图像一起处理,而之前它是独立处理它们的。

【讨论】:

  • 我想我有一个想法。您是否尝试过在不运行 combineImages 例程的情况下显示 $rgb ?我认为以某种方式发生的是所有 $red、$green 和 $blue 图像都以 24 位或 32 位图像的形式出现,其中 $red 的像素从 0x000000 到 0xFF0000,绿色来自0x000000 到 0x00FF00,蓝色是 0x000000 到 0x0000FF。展平图像本质上是添加图层。因此,它们不是真正的灰度,而是以颜色对齐的 RGB 形式出现。只是一个想法:-)
  • 有趣的想法,不幸的是,对 combineImages() 的调用显然非常重要。当我在没有那个调用的情况下尝试它时,我得到了一个完全灰度的图像。 combineImages() 是将灰度变为彩色的秘诀。
  • 当我试图解决它时,我发现生成的图像的颜色(当只是调用addImage() 多次然后combineImages())在青色、洋红色和黄色之间变化,所以我从色彩空间的角度攻击它。必须“展平”图像是有道理的,因为我相信 MagickWand 将 addImage() 视为只是将图像添加到列表中,而不是实际组合图像,而 combineImages() 只是对添加的最后一个图像做任何事情。 Flatten 告诉 MagickWand 实例同时对所有添加的图像进行操作。
【解决方案3】:

试试这个:

$im->addImage($red);
$im->addImage($green);
$im->addImage($blue);
$im->combineImages(imagick::CHANNEL_RED | imagick::CHANNEL_GREEN | imagick::CHANNEL_BLUE);

btw combineImages 不返回 imagick 对象,但 true/false 表示成功或失败,因此 $im 将包含您的组合图像。

编辑: 显然 combineImages 很糟糕,所以这里有一个替代方案:imagick::compositeImage

$im->compositeImage($red, imagick::COMPOSITE_COPY, 0, 0, imagick::CHANNEL_RED);
$im->compositeImage($green, imagick::COMPOSITE_COPY, 0, 0, imagick::CHANNEL_GREEN);
$im->compositeImage($blue, imagick::COMPOSITE_COPY, 0, 0, imagick::CHANNEL_BLUE);

【讨论】:

  • 根据us2.php.net/manual/en/imagick.combineimages.php,combineImages 确实返回一个 Imagick 对象而不是布尔值。我用这两种方法都试过了,虽然没有运气。假设它返回一个布尔值,在调用 combineImages 之后,我得到一个灰度图像(我假设是蓝色通道),假设它返回 Imagick,我得到一个青色阴影图像。
  • 您链接的页面有“成功时返回 TRUE”。在返回值标签下。添加了另一个可以使用的功能。
  • @c2h5oh greggory.hz 是正确的。 1) 文档对于 Imagemagick 扩展来说是可怕的(它都是从 MagickWand 文档复制/粘贴的),2) 该页面上的 description 声明该函数返回一个 Imagick 对象,3) 你似乎没有真正尝试过你自己的代码。
  • compositeImage方法会不会像-combine那样把灰度图转换成对应的RGB通道?
  • 所以我试了一下,它仍然是一个完全灰度的图像。我认为这是因为它只是复制指定的颜色通道,而不是使用灰度图像($red/$green/$blue)作为该颜色通道的大小。这就是 combineImages() 所做的。您是否尝试过任何不同结果的解决方案?
猜你喜欢
  • 2020-11-05
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 2014-10-02
相关资源
最近更新 更多