ImageMagick 示例 --
颜色基础和通道

索引
ImageMagick 示例前言和索引
什么是颜色
Gamma 校正和 sRGB 色彩空间
颜色规范
颜色通道
色彩空间
替换图像中的颜色 (替换特定颜色)
光栅图像,也就是 ImageMagick 通常处理的图像(一般来说)基本上由一系列单独的彩色点或像素组成。修改各个点及其表示方式是我们将在本节中探讨的内容。在下一节中,我们将探讨更一般的全局修改图像中整体颜色的方法。

什么是颜色?

要真正理解颜色,您需要准确地了解什么是颜色。在物理世界中,颜色实际上是一种错觉。我们之所以能看到颜色,是因为我们的眼睛以非常特殊且有限的方式感知物理世界。基本上,在我们的眼睛里,我们有专门的传感器来感知红色、绿色、蓝色,以及一个较小的传感器用于周边和低光照条件。后者是为什么我们在晚上只能看到灰色。 IM 图表有关更多信息,请参阅 维基百科,视锥细胞,右侧的图表是典型人眼对不同波长光的响应。正因为如此,我们只能根据红、绿、蓝电磁波长来感知世界,这就是为什么图像和图像处理通常都与红、绿、蓝或 RGB 相关的缘故。然而,情况也并非如此简单。我们的每个颜色传感器实际上都对一定范围的波长做出反应。例如,当我们看到黄光时,我们实际上是使用红色和绿色传感器来感知光的。如果我们的颜色传感器是严格的纯红色和绿色检测器,我们就不会看到任何黄色。彩虹实际上会在其中显示“间隙”。这意味着电视或电脑显示器实际上是在欺骗我们看到黄色,方法是显示器发出恰当混合的红光和绿光,而不是真正的黄光。我们的颜色传感器看到的强度与纯黄光相同,因此我们看到黄色,即使在现实中我们实际上看到的是两种不同的颜色频率。我们只是无法区分纯黄色和红光和绿光的混合。同样,蓝红色(紫色)的颜色实际上并不存在于单个特定的波长中,而仅仅是至少两种颜色频率的混合,尽管严格来说,紫罗兰是一种我们确实会做出反应的特定频率,主要由蓝色,以及其他两种传感器非常轻微地做出反应。请注意,我们实际上还有第四种视觉传感器,但它不是颜色,而是一个低光检测器,用于夜视,此时视锥细胞不再工作得很好。这就是为什么夜间看起来是单色的,月光都是灰色的。这个传感器也可能是 sRGB 色彩空间(见下文)在其非常暗的颜色中具有奇特的线性分量的原因为。补充说明:其他动物对我们有不同的传感器。蜜蜂和大多数其他昆虫都有紫外线传感器,因此对它们来说,我们的印刷图像、电视和广告牌可能毫无意义。更有可能的是,这些人工图像看起来更像是一幅相当可怕的伪彩色图像,而不是我们人类被欺骗看到的近乎完美的颜色。有些动物有 4 个颜色传感器,而另一些则只有一个(黑白)或两个。此外,有些动物比任何特定的颜色都更能看到运动。例如,公牛看不见红色,但能看见蓝紫色和绿色波长,但一顶摇摆的帽子会显示为“运动”颜色的闪光。对公牛来说,显示器的 50/60Hz 刷新周期可能会看起来像“运动”的闪光,而不是任何有意义的图像!有关更多信息,请参阅 维基百科,颜色视觉维基百科,颜色

RGB 色彩空间和通道

因此,RGB 色彩空间实际上是一种使用三个值(红、绿、蓝)表示图像的方法,这会让我们误以为自己在现实世界中看到了某些东西。因此,图像可以存储为 3 个数组值,三个值中的每一个都形成一个单独的像素或彩色点,以便显示。这三个值数组中的每一个都称为通道,它只是一个灰度图像,表示为我们的颜色传感器中的一个创建的光量。例如,以下是玫瑰图像的红色、绿色和蓝色分量。
[IM Output]
玫瑰
==> [IM Output]
红色
[IM Output]
绿色
[IM Output]
蓝色
请注意,“红色”图像比其他两个颜色分量亮得多,以显示玫瑰。但所有三个图像在底部附近的白色区域都非常亮。RGB 是加色现在,红、绿、蓝颜色被称为“加色”。也就是说,颜色加在一起形成最终的彩色图像。这是因为这些是我们眼睛看到的显性颜色,通过将它们组合在一起,我们可以有效地生成我们眼睛几乎可以看见的所有颜色。它们是加色的,因为从黑色(例如空白显示器)开始,您将添加红、绿、蓝光以生成我们看到的图像所需的适当颜色。关键在于,您从黑色或无光开始,然后添加适当数量的红、绿、蓝。您也可以通过在黑暗的房间里用三支手电筒(末端贴有红色、绿色和蓝色玻璃纸)照射同一个点来获得相同的效果。当三种颜色照射在同一个点上(例如白墙上)时,我们会看到白色。正是由于我们眼睛实际看到这些“主要”颜色的方式,彩色图像通常以 RGB 值表示,这些值也称为“颜色通道”。

CMY 色彩空间

打印时,您会遇到不同的问题。一张纸不能产生光,只能反射光。因此,您需要从一个向各个方向反射所有照射在其上的光的表面开始。也就是说,白色表面是什么。希望它反射的光本身是纯白光,无论是来自照射在窗户上的阳光,还是由我们人工照明的房间中的灯光产生的。现在,要在该纸上创建图像,您需要在该表面上涂抹墨水,这实际上会去除特定的光波长。由于我们“感知”红色、绿色和蓝色,因此这些是我们想要有选择地从反射自该白色纸张的光线中去除的颜色。因此,我们使用青色墨水去除红光,品红色去除绿光,黄色去除蓝光。生成特定颜色所需的青色、品红色和黄色墨水的量产生了所谓的 CMY 色彩空间。在这里,我生成了生成玫瑰图像所需的墨水蒙版,仅使用青色、品红色和黄色墨水(假设墨水是“线性的”)
[IM Output]
玫瑰
==> [IM Output]
青色
[IM Output]
品红色
[IM Output]
黄色
也就是说,青色蒙版值越亮,去除更多红色所需的青色墨水就越多。换句话说,青色蒙版是我们希望纸张反射的红光量的精确反面。事实上,上面所有三个通道图像都是 RGB 色彩空间生成的图像的精确反面。因此,要将 RGB 图像转换为 CMK 图像,您真正需要做的就是 反转图像,然后将图像声明为 CMY 色彩空间。由于我们是有选择地去除波长,因此青色、品红色和黄色被称为“减色”。

CMYK 色彩空间

选择性去除波长带来的主要问题是,仅仅通过涂抹所有三种青色、品红色和黄色墨水来去除所有红、绿、蓝光,实际上并不能去除所有反射的光。结果,您得到的将不是黑色,而是一种难看的泥土棕色。墨水(或滤光片)并不完美,就像我们自己的眼睛并不完美一样。正如我之前提到的,我们的每个颜色传感器看到的不仅仅是一种波长的光,而是一系列我们解释为“红色”、“绿色”或“蓝色”(或这些颜色的混合)的波长。以至于我们的“蓝色”光传感器实际上可以(尽管不是很好)看到一些紫外线。补充说明:“黑光”的滤光片是有意设计成不完美的,以便我们“刚好能看到”来自这种灯的光,这样我们就能知道它是否打开。正是由于 CMY 墨水的这种“泄漏”以及我们自己不完美的眼睛,我们还在混合物中添加了纯黑色墨水,使其可以用来消除从纸张反射的所有光。为了避免与蓝色混淆,黑色墨水或通道被分配字母 K。因此,对于打印,我们使用四种颜色的墨水:青色、品红色、黄色和黑色;并使用这些墨水定义图像,以形成 CMYK 色彩空间。例如,以下是从此图像中分离出的相应的 CMYK 分量。
[IM Output]
玫瑰
==> [IM Output]
青色
[IM Output]
品红色
[IM Output]
黄色
[IM Output]
黑色
请注意,青色、品红色和黄色的数量已减少,现在比 CMY 色彩空间中的颜色更暗,因为它们的用途被相应数量的黑色所取代。也就是说,当某个像素存在所有三种墨水时,将使用黑色。因此,例如要打印纯黑色,您只需使用纯黑色墨水,而无需使用任何其他墨水。请记住,上面提到的“黑色”是在纸上涂抹的黑色墨水的量,因此灰度通道图像越亮,应使用的黑色墨水就越多。因此,它也是一个看起来负面的图像,就像其他三个图像一样。当然,在彩色打印机中添加纯黑色可以使打印黑色文本变得更加简单,因为您不再需要打印三种不同的墨水,并完美地叠加在同一个点上,以生成纯黑色的线条、字母和形状。这意味着更少的墨水,纸张变得不太“湿”,也不太可能晕染或污损,这对于打印机来说尤其好。有关 RGB 和 CMYK 颜色工作原理的另一个类似讨论,请参阅以下内容的介绍页面: XaraXone 工作簿,定义颜色

其他色彩空间

其他色彩空间只是表示相同颜色或我们不完美的眼睛还可以分辨出的一些其他颜色的其他方式。但是,这些色彩空间对使用显示器显示这些颜色或打印这些颜色几乎没有影响。它们基本上表示处理和/或处理图像颜色的其他方法,以便增强或突出显示特定内容,例如...
  • 更好地处理暗色非线性 (sRGB)
  • 颜色彩虹和色调 (HSB、HSL、HSI、OTHA 色彩空间 - 未保留强度)
  • 标准化定义颜色 (XYZ)

  • 精确或感知颜色差异(LABLUV 色彩空间,以及它们的 LCHab 和 LCHuv 循环色调等价物)
  • 扩展的高动态范围(用于 HDRI 图像)(scRGB
  • 更好的颜色值压缩(例如在 YIQYUV 中)
  • 电视传输(YCbCr、YPbPr,其中 Y = BW 信号)
我还没有提到的最后一个色彩空间是“灰度”,但这只是一个简单的像素值单数组。你如何解释这些值是可变的,因为它们可以表示许多不同的东西。通常,这样的图像被认为是线性灰度,类似于线性 RGB(与非线性 sRGB 相反)。IM 版本 6 实际上没有这样的灰度色彩空间,并且只用线性 RGB 色彩空间伪造它,将所有 RGB 设置设置为相同的值。如果三个值不相同,则图像不再是灰度。IM 版本 7 灰度是一个单通道图像(内存使用量更小)。
以上对图像“色彩空间”的更改只是图像在内存中颜色的粗略排列。它还提供不同色彩空间之间非常基本的(简单的)颜色转换。

对于精确的颜色规格和颜色转换,应改用颜色配置文件,但仅在使用可以处理颜色配置文件的图像文件格式时才有效。


伽马校正和 sRGB 色彩空间

人类颜色感知

在上面我们看到你可以用很多不同的方式表示图像。我们上面查看的所有色彩空间都被称为“线性”色彩空间,这意味着使用的实际值表示图像中颜色的实际“强度”值。
然而,现实生活永远不会如此简单。它永远不会!例如,让我们生成并保存一个具有简单线性灰度序列的图像…

  magick -size 100x100 gradient:'gray(100%)-gray(0)' \
          -set colorspace sRGB gradient.gif
[IM Output]
备注…
  • 使用“gradient:'gray(100%)-gray(0)'”确保 IM 生成线性 RGB 数据的渐变,这将位于线性 RGB 色彩空间中。
  • “-set colorspace sRGB”告诉 IM 这个“线性”渐变实际上位于“sRGB”中,因此在保存到只能存储 sRGB 色彩空间值的 GIF 图像文件格式时不需要“校正”。
现在,此图像中使用的实际颜色值是线性渐变,应该从顶部的白色平滑地更改到底部的黑色,中间是完美的数学精确的 50% 灰色。但是,如果您查看图像,您会发现图像实际上似乎包含比亮色(接近白色)颜色更多的暗色(接近黑色)颜色。为什么?当给定仅为其最大范围(“白色”)一半的光强度时,人类视觉不会看到颜色值指示的纯中间色灰色,而是看到更暗的颜色。结果,上述线性渐变看起来不像从白色到黑色的颜色均匀线性扩展,而是具有比应有的更多的暗色。实际图像值到感知值的粗略“幂函数”形式为…
perceived_grey = value2.2

值“2.2”是大多数人类的典型平均伽马函数值。

Gamma 校正

伽马校正是一种调整实际保存的颜色值的方法,以便最终图像在颜色扩展方面看起来更加均匀。基本上,虽然人类视觉使用 2.2 的幂因子使光线看起来更暗,但为了使线性图像“看起来”线性,我们需要反转该幂函数,使用 1/2.2 的值。也就是说,为了使图像看起来线性,我们需要使用以下公式对其进行校正…
gamma_corrected_value = value1/2.2

IM 通过级别运算符,伽马参数或更具体地通过伽马运算符提供伽马校正。但是,您也可以使用评估 POW 函数直接修改图像值。

所以让我们应用它并查看“伽马校正图像”的结果…

  magick -size 100x100 gradient:'gray(100%)-gray(0)' -gamma 2.2 \
          -set colorspace sRGB gradient_gamma.gif
[IM Output]
请注意,图像现在具有更多数量相等的光线和暗色。但是,图像中的实际值不再是“线性”,这在以后处理此图像时可能会导致问题。伽马校正只是调整颜色以使图像“看起来”正确的粗略“快速”方法。它不是校正人类响应图像的常用方法,甚至不是最佳方法。有关图像处理伽马校正的更具体示例,请参阅使用伽马校正调整大小有关伽马校正的更多信息,请参阅您可能还想查看“-auto-gamma”运算符,它尝试调整伽马以生成线性 RGB 图像,并具有等量的光线和暗色(在线性空间中)。

显示器的 Gamma 值

从显示器后退几米(码),然后查看左侧的图像。如果您的显示器(和网络浏览器)正确显示 sRGB 图像,则中心“散列”图案的亮度与周围 sRGB 渐变大致相等的点应位于正中间。大多数计算机显示器都无法通过此测试!但是 HDMI 电视应该完美呈现。该图像是使用…创建的。

  magick -size 45x256 gradient: -size 10x256 pattern:gray50 \
          -duplicate 1,0 +append -set colorspace sRGB -colorspace RGB \
          monitor_sRGB.png
[IM Output]
以下是一些具有不同“伽马”级别的类似图像,因此您可以查看您的显示器与人类感知的正确“2.2”伽马显示有多接近。

  for gamma in 1.6 1.8 2.0 2.2 2.4
  do
    magick -size 45x256 gradient: -size 10x256 pattern:gray50 \
            -duplicate 1,0 +append -gamma $gamma monitor_g$gamma.png
  done
[IM Output]
伽马 1.6
[IM Output]
伽马 1.8
[IM Output]
伽马 2.0
[IM Output]
伽马 2.2
[IM Output]
伽马 2.4
当您后退时,亮度相等的点大约在 50% 标记处的图像会告诉您显示器的粗略伽马级别。如果正确调整,您的显示器应具有 2.2 的伽马级别,这与 sRGB 色彩空间非常匹配。当我编写本文时,我的旧屏幕(工作提供)非常糟糕。它具有大约 1.8 的伽马设置,并且显示器顶部(较暗)的伽马实际上与显示器底部(较亮)的伽马不同。这在我比较屏幕上不同位置的图像时给我带来了问题,因为相同的图像在垂直放置在不同位置时看起来不同!另一方面,我的个人笔记本电脑(当时)具有非常均匀的显示,根据以上内容,具有合理的 2.0 伽马设置。

sRGB 色彩空间校正

使用 sRGB 色彩空间保存图像与伽马校正图像非常相似,但稍微复杂一些,以便更好地再现人眼的实际响应,特别是对于非常暗的颜色阴影。
所以让我们在 sRGB 校正的色彩空间中保存我们的线性渐变。

  magick -size 100x100 gradient:'gray(100%)-gray(0)' \
          -set colorspace RGB -colorspace sRGB    gradient_sRGB.gif
[IM Output]
从 IM v6.7.7 开始,以上内容简化为

  magick -size 100x100 gradient:white-black gradient_sRGB.gif
这是因为线性渐变将始终在线性(RGB)色彩空间中生成(这是运算符工作唯一合理的方式)。

但是,由于请求了 sRGB 颜色“白黑”,因此线性数据渐变将自动转换为 sRGB 色彩空间,生成非线性数据值和感知线性渐变。

在 IM 6.7.5 版本之前,以上内容将失败,因为 IM 将“sRGB”和“RGB”色彩空间的含义反转了。因此,在较旧版本的 IM 上,需要交换这两个色彩空间名称。例如…

  magick -size 100x100 gradient: -set colorspace sRGB \
          -colorspace RGB gradient_sRGB.gif
这种色彩空间处理怪异被认为是 IMv7 的长期错误,尽管旨在仅在 IMv7 中修复,但它被反向移植到 IMv7。

请注意,以上内容(或任何其他渐变)都不是完美的,因为完美根本不可能,每个人都以自己的方式看待事物,存在细微的差异。简单地说:你所看到的,永远不会完全是其他人所看到的(这实际上非常禅意)。所有 sRGB 都是根据大量调查和许多印刷/绘画/色彩专家,对大多数人来说非常好的近似值。有关精确 sRGB 公式的详细信息,请参阅维基百科,sRGB 色彩空间。已经开发出更完整、更准确的“人类亮度响应”,并且可以在论文人类视觉,刚刚注意到的差异中在线查看。这包括在主要照明变化情况下自适应响应。万维网已将sRGB标准化为推荐的(并且仍然相当简单)默认色彩空间,因此应将其用于所有不包含任何色彩空间配置文件信息的图像。也就是说,对于 GIF、PNG、JPEG 和 TIFF 等图像。所有这些格式(除了 GIF)都允许使用颜色配置文件来明确指定图像的色彩空间。但是,PbmPlus等图像文件格式通常不被视为位于 sRGB 色彩空间中。因此,在处理此类文件格式时,通常最好使用“-set colorspace ...”以确保色彩空间符合您的预期。以下三张图像一起显示,以便您可以比较它们。
[IM Output]
线性
[IM Output]
伽马
[IM Output]
sRGB
正如您所看到的,伽马和 sRGB 校正图像几乎相同,并且绘制的差异实际上非常小。因此,虽然使用sRGB是更正确的方法,但使用伽马校正可能更容易应用。sRGB 和伽马图像之间最大的差异在于极暗的图片。对于 8 位灰度值为 1,sRGB 比等效伽马亮 60 倍。值为 8 的亮度是 5 倍。在大多数情况下,这不会产生任何明显的差异,但在处理非常暗的图片时可能会产生差异。

处理真实图像

大多数图像处理运算符并不关心图像使用什么色彩空间,它只是将其操作应用于通道数据,而不管其色彩空间如何。尽管有些操作必须为处理“黑色”的额外通道数据付出特殊努力,并且正如您将在后面看到的“Alpha”(或“Alpha”透明度)。但是,图像的色彩空间会极大地影响许多操作的最终结果。因此,在不同的色彩空间中进行图像处理可以产生改进的结果。此示例更清楚地显示了为什么在 sRGB 中处理不是一个好主意。来自 IM 用户论坛上关于颜色模糊和“损坏颜色”的讨论。
我们使用不同的颜色通道获取两种颜色,并将它们模糊在一起,以便在通道内颜色模糊到零(低颜色值)。首先,让我们使用默认的 sRGB 输入通道执行此操作。

  magick -size 40x80 xc:red xc:lime +append \
          -blur 0x20 blur_sRGB.png
[IM Output]
如果您查看结果,它看起来像是颜色从红色模糊到黑色,然后到绿色。也就是说,因为在 sRGB 色彩空间中,我们眼睛看到的值看起来比它们应该的更暗。
在这里,我再次模糊相同的图像,但使用线性 RGB 色彩空间。


  magick -size 40x80 xc:red xc:lime +append \
          -colorspace RGB -blur 0x20 -colorspace sRGB blur_RGB.png
[IM Output]
正如你所见,这次我们得到了一个更合理的颜色结果,红色和绿色颜色虽然模糊但过渡到橙色。使用其他线性色彩空间,如 LAB 或 LUV,也能得到类似的结果,我们将在下面详细介绍。基本上,在处理涉及颜色混合的图像时,例如在颜色量化(颜色减少)等操作中,以及在图像缩放和更一般的图像变形中,为了获得更准确的结果,你应该在线性色彩空间中处理图像,尽管实际上很少有人这样做。
Helmut Dersch(著名的桶形畸变和镜头校正专家)建议你应该考虑使用线性“LAB”色彩空间来处理图像,特别是对于缩放和图像变形。

我建议你只在进行图像绘制、合成、缩放或变形时,才将图像从“输入”sRGB色彩空间转换到其他“线性”色彩空间。无论是线性RGB、LAB还是LUV,差别都不大。

例如,以下是三种主要线性色彩空间中的红蓝模糊效果。我选择这些颜色是因为它们在生成的中间颜色中似乎显示出最大的差异。

  for colorspace in RGB LUV LAB
  do
    magick -size 80x40 xc:red xc:blue -append \
            -colorspace $colorspace -blur 0x30 -colorspace sRGB \
            colorspace_$colorspace.png
  done
[IM Output]
RGB
[IM Output]
LUV
[IM Output]
LAB
有关处理图像与色彩空间相关的更多示例,请参阅使用色彩空间校正进行缩放。另请参阅有关颜色名称和在线性色彩空间中绘制的警告,请参阅使用伽马和色彩空间校正进行绘制

颜色规格

在 IM 中,颜色可以用多种方式指定。关于这方面的最佳指南可以在官方 IM 网站上找到颜色名称

颜色名称

许多颜色都有特定的名称,这使得它们更容易使用。例如,“RoyalBlue”是一种非常漂亮的亮蓝色。[IM 输出]右侧是包含所有命名颜色的图像,包括ImageMagick中可用的带数字的颜色。这些颜色首先被分成三组:浅白色、中间色调和深色,然后绘制在三个单独的HSL色轮上,每个色轮都有不同的垂直偏移。纯白色和黑色出现在图表的最顶部和底部作为单独的点,形成垂直范围的极值。生成它的脚本是“hsl_named_colors”,并遵循在分层图像的程序化定位中介绍的技术。
从技术上讲,因为我以“双锥体”而不是“圆柱体”的三维形式绘制HSL颜色,所以每个颜色点的半径被设置为颜色的“色度”(“饱和度”/“亮度”),而不仅仅是它的“饱和度”。请参阅维基百科:HSL 和 HSV

为了更准确,也应该使用六边形棱锥而不是圆锥,但这计算起来要困难得多,而收益却很少。

如你所见,有很多颜色名称与红色到黄色相关联,而在青色到绿色的色调中则有一小组。在偏白色黄色和青色中也有类似的聚类。但在偏绿色颜色方面却很少有命名颜色。本质上,HSL色彩空间的某些区域几乎没有命名颜色。可能难以找到要使用的特定命名颜色。但是,通过将右侧的图像加载到IM“display”程序中,你可以使用鼠标中键查看已绘制的特定颜色的ImageMagick颜色名称。

特殊颜色名称

有一些特殊颜色,用于ImageMagick中的特殊用途。“None”或“Transparent”是一种完全透明的黑色,通常用于指定背景透明度,例如在创建纯色画布时,或在使用图像图层时。“Opaque”只是“Black”的别名,因此很少使用。它通常只在想要表示任何不透明颜色时使用,例如在进行Alpha通道处理时。

颜色名称冲突

颜色名称可以来自三个不同的来源:SVG、X11 和 XPM,并且大多数名称产生的颜色相同,而不管定义的来源是什么。但有一些颜色名称会产生不同的颜色,具体取决于使用的颜色规范。最大的问题是SVG颜色“Green”(半亮绿色)与X11/XPM颜色“Green”(纯RGB绿色)不同。如果你想要纯绿色,最好使用SVG颜色名称“Lime”,它没有冲突。维基百科有一篇关于颜色名称冲突的优秀文章,以及一个关于实际颜色名称的良好表格,在X11 颜色名称中。你可能还想查看文章网页颜色,它提供了一组排列整齐的某些颜色范围的表格。最显著的冲突存在于四种特定的颜色中。以下是一张已知颜色名称冲突的表格。请记住,IM默认使用SVG颜色。
冲突
颜色名称
SVG结果
(IM默认)
X11结果
用于名称
X11等效
名称
替代
颜色名称
绿色 #008000 #00FF00 Lime
Maroon #800000 #B03060 FireBrick
Purple #FF00FF #A020F0 品红色
Gray #7E7E7E #BEBEBE Grey
关于以上内容的说明...
  • X11“Grey”是一种视觉上的中间灰色。它也非常接近(但并不完全相同)于X11颜色“Gray74”和SVG颜色“Silver”(“gray(192)”)。
  • 默认(SVG)“Gray”非常接近完美的数学灰色,最好使用颜色名称“Gray50”或“gray(128)”(对于8位使用)来指定。
  • 由于所有命名颜色都使用8位(0-255)值指定,因此它们都不能生成完美的16位纯灰色!
  • 当需要灰色进行数学处理时,例如FFT直流相位边缘检测阴影图像合成照明效果相对位移映射,你最好使用颜色公式“gray(50%)”,它可以在任何颜色位深度生成完美的数学中间色调灰色。
选择特定用途的颜色时,建议谨慎

颜色和色彩空间

虽然许多颜色都有名称,但图像中发现的大多数颜色都没有,它们只是一组值,通常为3个,用于指定特定颜色。然而,仅凭三个值并不能完全定义颜色,你还需要指定这些值所属的“色彩空间”或“颜色系统”。以上所有“命名”颜色都位于sRGB色彩空间中,这是它们定义所在的色彩空间。但有时你希望在不同的色彩空间中定义颜色。例如,在HSL、CYMK甚至XYZ颜色中。ImageMagick可以做到这一点,你可以在ImageMagick颜色名称中看到这些规范的详细信息。未来:使用其他色彩空间的示例(仍在开发中)
虽然ImageMagick中的RGB表示线性RGB色彩空间,但普遍接受的做法是,“rgb(value,value,value)”的颜色名称实际上是在定义sRGB颜色

要实际定义线性RGB颜色而不是sRGB颜色,请使用颜色公式“icc-color(RGB,value,value,value)”(见下文)。
从IM v6.7.8-3开始,你可以使用函数“icc-color(colorspace,color...)”来定义颜色或重新定义特定颜色的色彩空间。未来:使用示例

半透明颜色

你只能以两种不同的方式直接指定半透明颜色。设置半透明颜色的最常用方法是使用十六进制值。例如,以下是一些颜色规范,显示了不同级别的颜色透明度。我已经在背景图案上显示了生成的彩色图像,以便你可以看到图案穿过图像透明度。

  magick -size 50x50    xc:'#00FF00FF'   color_hex_1.png
  magick -size 50x50    xc:'#00FF00C0'   color_hex_2.png
  magick -size 50x50    xc:'#00FF0090'   color_hex_3.png
  magick -size 50x50    xc:'#00FF0060'   color_hex_4.png
  magick -size 50x50    xc:'#00FF0030'   color_hex_5.png
  magick -size 50x50    xc:'#00FF0000'   color_hex_6.png
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
在IM v6.3.0之前,最后一组十六进制数字包含以“蒙版”或“不透明度”值的形式表示的颜色透明度。也就是说,最后的十六进制“00”表示“不透明”,而“FF”表示透明。

然而,在IM v6.3.0之后,此值被反转,以便表示“alpha”透明度值,使IM符合SVG标准和其他图形软件包。换句话说,“FF
”现在表示完全不透明,“00”表示完全透明。
你也可以使用特殊的“rgba()”颜色函数来指定颜色。其中RGB值从0到255,alpha通道指定为0.0(透明)到1.0(不透明)之间的十进制分数。

  magick -size 50x50   xc:'rgba(255,0,0, 1.0)'   color_rgba_1.png
  magick -size 50x50   xc:'rgba(255,0,0, 0.8)'   color_rgba_2.png
  magick -size 50x50   xc:'rgba(255,0,0, 0.6)'   color_rgba_3.png
  magick -size 50x50   xc:'rgba(255,0,0, 0.4)'   color_rgba_4.png
  magick -size 50x50   xc:'rgba(255,0,0, 0.2)'   color_rgba_5.png
  magick -size 50x50   xc:'rgba(255,0,0, 0.0)'   color_rgba_6.png
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
在IM 6.2.7版本之前,“rgba()”也使用蒙版值作为alpha通道值。也就是说,值0表示完全不透明,255表示完全透明。这已根据“W3C CSS3颜色模块推荐规范”,作为IM更符合其他图像标准(特别是WWW和SVG使用)的一部分而更改。
目前无法通过名称直接指定半透明颜色,并带有额外的alpha值设置。但是,你可以通过生成该命名颜色,然后修改图像的透明度来实现它。你还需要额外注意,你必须设置Alpha通道,然后才能实际设置颜色的透明度。

  magick -size 50x50   xc:RoyalBlue                   color_name_1.png
  magick -size 50x50   xc:RoyalBlue -alpha set \
                        -channel A -evaluate set 80%   color_name_2.png
  magick -size 50x50   xc:RoyalBlue -alpha set \
                        -channel A -evaluate set 60%   color_name_3.png
  magick -size 50x50   xc:RoyalBlue -alpha set \
                        -channel A -evaluate set 40%   color_name_4.png
  magick -size 50x50   xc:RoyalBlue -alpha set \
                        -channel A -evaluate set 20%   color_name_5.png
  magick -size 50x50   xc:RoyalBlue -alpha set \
                        -channel A -evaluate set  0    color_name_6.png
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
是的,这很麻烦,如果能够将透明度设置为颜色名称规范的一部分就好了。如果你希望看到这一点,请在IM开发者论坛上提出请求。也可以使用MVG绘制设置绘制命名填充颜色,不过你需要一个透明的起始画布才能使其正常工作。例如...

  magick -size 50x50 xc:none \
          -draw "fill Tomato fill-opacity 0.5 rectangle 0,0 49,49" \
          color_name_draw.png
[IM Output]
请注意,完全透明的颜色虽然完全不可见,但仍然具有颜色。然而,大多数IM操作符都认识到,任何完全透明的颜色都与任何其他完全透明的颜色相同。由于这一点以及内部数学运算的方式,许多操作符通常会用完全透明的黑色(也称为特殊颜色“none”)替换完全透明的颜色。

颜色通道

图像的实际颜色数据存储为值的数组,称为通道。通常,图像至少有3个通道,分别表示红色、绿色和蓝色的颜色值。但如上所述,存储的值可以表示其他色彩空间。

色彩空间和通道命名

-colorspace” 运算符的主要目的是改变 IM 在内存中存储图像颜色方式。通常每个图像有 3(或 4)个图像数据通道。图像的当前“颜色空间”决定了每个通道的数据代表什么。现在通常通道被命名为“红色”、“绿色”、“蓝色”,因为这通常是存储在这些通道中的图像数据类型。然而,情况并非总是如此。不要把“R”或“红色”通道想象成红色,把它想象成“通道 1”,它可以包含“红色”、“色相”、“青色”或其他数据,具体取决于图像的颜色空间。“红色”只是通常用于“红色”或第一个通道的通道标签。第二常用的颜色空间是“CMYK”,它定义了应用于使“白色”纸张变暗的彩色“墨水”的量(减色颜色空间)。请注意,K 是“blacK”(黑色)的缩写,它是图像的负强度值。由于这非常常见,“RGB”通道也有“青色”、“品红色”和“黄色”的替代命名,或者只是字母“C”、“M”和“Y”,尽管实际上它们指的是与“RGB”图像使用的相同通道集。还有一个特殊的第四个颜色通道用于“黑色”或“K”颜色通道。这基本上意味着“Green”(绿色)的颜色通道实际上指的是与“Magenta”(品红色)使用的完全相同的颜色通道。数据本身是“绿色”还是“品红色”取决于图像在内存中的“颜色空间”,而不是通道的名称。其他颜色空间也是如此。例如,使用“LAB”颜色空间意味着“红色”通道包含“亮度”值,“绿色”通道包含“A”(或红绿)值,“蓝色”通道包含“B”(或蓝黄)值。
类似地,“Alpha”('A')、“Opacity”('O')和“Matte”都是指图像透明度信息的“-channel”设置的别名。'alpha' 通道是 'matte' 通道的反向并不重要,它仍然指的是同一个通道,并产生相同的结果,即图像的内部蒙版通道。运算符是否将内部 alpha 通道数据视为'alpha'值取决于运算符。像“-threshold”这样的低级通道运算符作用于内存中通道的原始'matte'数据。但是,大多数高级运算符,如“-fx”和“-composite”,将该数据视为表示'alpha'数据,用于操作目的。还有一种控制存储的图像数据的颜色空间的方法。“-set colorspace”(IM v6.4.3-7 中添加)只会更改内存中的'颜色空间'设置。也就是说,它可以将 RGB 图像转换为 HSL 图像,而无需更改或修改图像正在使用的实际像素数据。最典型的用法是在手动组合通道数据以设置组合图像的最终颜色空间时。
所以让我们看看如何操作颜色通道。请记住,每个通道只是一个值数组。然后所有通道将组合在一起,以表示图像中每个像素的实际颜色。

分离通道图像

分离单个颜色通道最简单的方法是使用“-separate”运算符提取每个通道的当前内容作为灰度图像。

  magick rose: -channel R -separate separate_red.gif
  magick rose: -channel G -separate separate_green.gif
  magick rose: -channel B -separate separate_blue.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
请注意,红色玫瑰在红色通道图像中很突出,而在蓝色和绿色通道中则相当暗淡。另一方面,绿色叶子在绿色通道中很突出,但在其他通道中则不突出。图像底部附近的白色在所有通道中都很亮。
在 IM v5 及之前的版本中,“-channel”不仅是后续图像操作的设置,而且在某些情况下还是一个将指定通道转换为灰度图像的“图像运算符”。非常令人困惑!

在 IM v6 中,“-separate”被创建出来是为了将这两个截然不同的任务分开。“-channel”选项仅用于后续图像操作的设置,而“-separate”将提取指定的通道到单独的灰度和完全不透明的图像中。

从 IM v6.2.9-3 开始,“-separate”运算符允许您根据“-channel”设置分离多个颜色通道。“-channel”设置中的项目数量将决定创建的图像数量(按 RGBA 顺序)。例如,由于默认的“-channel”设置为'RGB',因此默认操作是创建三个图像,如下所示。

  magick rose: -separate separate_RGB_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
这里我们使用“-colorspace”运算符将 IM 存储图像颜色数据的方式转换为CMYK 颜色表示。然后我们提取相关的四个颜色通道。

  magick rose: -colorspace CMYK -separate separate_CMYK_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
最后一幅图像('Black' 或 'K' 通道)尤其有趣,因为它似乎是原始图像的负灰度图像。实际上,它表示 CMYK 打印机应在纸上沉积的“墨水”量,从而减少其他颜色通道所需的色彩量。请注意,默认情况下,“-channel”设置不包括图像的特殊蒙版透明度通道。如果要始终生成所有存在的通道,可以使用“-channel ALL”通道设置,或使用'RGBA'或'CMYKA'“-channel”设置。

颜色空间表示中的灰度通道

您可以从颜色空间中提取特定的通道值以用于特殊目的。例如,这里我们使用多种不同的表示方法从玫瑰图像中提取图像的灰度亮度或强度。

  magick rose: -colorspace Gray                      channel_gray.gif
  magick rose: -grayscale Rec709Luma                 channel_luma709.gif
  magick rose: -grayscale Rec601Luma                 channel_luma601.gif
  magick rose: -colorspace HSI  -channel B -separate channel_average.gif
  magick rose: -colorspace HSL  -channel B -separate channel_lightness.gif
  magick rose: -colorspace HSB  -channel B -separate channel_brilliance.gif
  magick rose: -colorspace CMYK -channel K -negate -separate channel_black.gif
  magick rose: -colorspace LAB  -channel R -separate channel_lab_light.gif
[IM Output]
Gray
Gray
[IM Output]
Rec709Luma
[IM Output]
Rec601Luma (Y)
YUV/YIQ
[IM Output]
平均值 (I)
HSI/OHTA
[IM Output]
亮度
HSL
[IM Output]
明度
HSB
[IM Output]
负黑
CMYK
[IM Output]
亮度*
LAB / LUV
有关实际公式,请参阅“-colorspace”选项的官方参考。请注意,从 IM v6.7.7 开始,灰度图像在内存中和保存时均未进行伽马或 sRGB 修改。因此,它们往往比该版本之前的版本更暗。请注意,“灰色”(也称为“强度”或更准确地说是“亮度”)和 YUV 颜色空间的“亮度”是等效的。类似地,HSB 颜色空间的“明度”和 CMYK 颜色空间的负“blacK”(黑色)通道是等效的(并且通常对于灰度使用来说过于明亮)。请注意,LAB(以及 LUV)颜色空间的“亮度*”通道(不要与 HSL 的“亮度”混淆)被认为与人类视觉感知最匹配,尽管它通常不用于生成灰度图像。请注意,如果给定灰度图像,所有颜色空间灰度图像都会生成与输入灰度图像完全相同的图像,除了 LAB / LUV 颜色空间的“亮度*”('R')通道图像。

其他通道分离方法

一种方法是将一个通道复制到所有其他通道,以生成灰度图像,就像分离运算符生成的灰度图像一样。一种简单但缓慢的方法是使用FX DIY 运算符

  magick rose: -fx R channel_red.gif
  magick rose: -fx G channel_green.gif
  magick rose: -fx B channel_blue.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
这通常被认为是最容易理解的“最简单”解决方案,并且已在其他 IM 教程中使用过。其他方法涉及使用多种技术将不需要的通道“清零”。这些列在下面的清零颜色通道中,并且通常比使用“-fx”快得多。

组合 RGB 通道图像

分离出所有图像颜色通道并处理它们后,您还需要能够将图像重新组合在一起。这可以通过使用特殊的列表运算符“-combine”来完成,它基本上与“-separate”完全相反。

  magick separate_red.gif separate_green.gif separate_blue.gif \
           -combine -set colorspace sRGB rose_combined.gif
[IM Output] [IM Output] [IM Output] ==> [IM Output]
然后这些“-combine”创建了一个声明为 sRGB 颜色空间图像的图像。一个用户想要能够交换图像的红色和蓝色通道,这使得它很容易,分离通道,交换,然后重新组合。

  magick rose: -separate -swap 0,2 -combine rose_rb_swap.gif
[IM Output]
请记住,默认的“-channel”设置为'RGB',并定义了哪些图像通道图像正在组合在一起。如果未定义所有正在组合在一起的通道,则其他通道将使用当前的“-background”设置中的颜色值进行设置。但是,您应该注意,“-combine”和“-separate”都会忽略“-channel”定义通道的顺序。对于“-channel”设置中的每个通道集,通道将始终按照标准的'Red,Green,Blue,Matte'通道顺序进行处理和生成。因此,即使您使用“-channel BR”设置或仅使用“blue,red”,“-combine”运算符仍然期望这两个图像首先为红色,然后为蓝色。绿色和 alpha 值(如果图像具有透明度)将设置为当前“-background”设置值。例如……

  magick separate_red.gif separate_blue.gif -background black \
           -channel blue,red  -combine    rose_red_blue.gif
[IM Output] [IM Output] ==> [IM Output]

组合非 RGB 通道图像

从 IM v6.4.3-7 开始,您还可以“-combine”表示其他颜色空间的通道图像,但您需要告诉 IM 结果图像应是什么颜色空间。这是通过使用特殊的“-set colorspace”运算符来完成的。这基本上会更改内存中图像的颜色空间,但不会映射图像的像素数据,使其保持原样。组合图像到正确的颜色空间后,您可以使用普通的“-colorspace”运算符将像素数据映射回正常的 RGB 数据。

  magick separate_HSB_?.gif  -set colorspace HSB  -combine  \
          -colorspace sRGB  rose_HSB_combined.gif
[IM Output]
此方法也适用于 CMYK 图像,由于需要第四个颜色通道,因此通常难以处理。

  magick separate_CMYK_?.gif  -set colorspace CMYK  -combine  \
          -colorspace sRGB  rose_CMYK_combined.gif
[IM Output]
另一种解决方法(适用于早期版本的 IM)是加载一个图像(红色通道)并将其更改为正确的颜色空间。之后,可以加载每个单独的通道图像并通道复制到该预准备的图像中。

  magick separate_HSB_0.gif -colorspace HSB \
          separate_HSB_0.gif -compose CopyRed   -composite \
          separate_HSB_1.gif -compose CopyGreen -composite \
          separate_HSB_2.gif -compose CopyBlue  -composite \
          -colorspace sRGB   rose_HSB_combined_alt.gif
[IM Output]
当然,如果您使用了“-set colorspace”操作,则第一个通道的数据将已到位,因为这不会更改实际的像素数据,只会更改数据解释方式。
最后一个示例不适用于'CMYK'图像,因为'Black'通道图像实际上不包含黑色通道!因此,“-compose CopyBlack”将无法找到有效的数据进行复制。我认为这是一个错误,但目前不太可能修复。

使用其他颜色空间可能很有用。例如,这里我获取内置的玫瑰图像,并希望在'Lab'颜色空间中反转图像的亮度通道。完成后,我重新组合以再次构建 sRGB 图像。

  magick rose: -colorspace Lab -separate \
          \( -clone 0 -negate \) -swap 0 +delete \
          -combine -set colorspace Lab \
          -colorspace sRGB   rose_light_neg.gif
[IM Output]
之前此示例使用'HSL'颜色空间,但这是一个线性颜色空间,我们希望在'Lab'提供的“感知颜色空间”中进行反转。



请注意,图像仍然具有相同的颜色,但颜色的亮度(明度)被反转,产生了奇怪的效果。您可以用您自己的操作集替换“-negate”来调整图像的亮度级别。但是,由于“-negate”本身就是一个通道控制运算符,因此我们不必“-separate”分离亮度通道来对其进行反转。

  magick rose: -colorspace Lab \
          -channel R   -negate   +channel \
          -colorspace sRGB rose_light_neg2.gif
[IM Output]
如您所见,这简化了操作,但在您想要实现的效果中,这可能并不总是切实可行的。

清零颜色通道

有时您有一个图像(RGB 或其他颜色空间),您只想清除或“置零”一个或两个颜色通道,但保持所有其他通道不变。例如,要创建灰度图像而不使用 RGB 灰度化技术,您可以在 HSL 颜色空间中“置零”饱和度通道('G'),从而创建灰度图像。“色相”值在饱和度为零时没有意义,因此您只剩下一个灰度图像。最直接的技术通常是使用 评估运算符 将不需要的通道中的所有值置零……

  magick rose: -colorspace HSL \
          -channel G  -evaluate set 0  +channel \
          -colorspace sRGB rose_grey.gif
[IM Output]
但是,还有许多不那么明显的方法可以做到这一点……


  # Evaluate (fast and direct)
    -channel G -evaluate set 0 +channel

  # FX zeroing (direct simple, but slow)
    -channel G -fx 0 +channel

  # Separate the channels you want to keep,
  # then combine using a background color to set the other channels
    -channel RB -separate -background black -combine +channel

  # Gamma which is a miss-use of the operator, but works VERY well!
  # ( 1 = leave alone;  0 = zero channel;  -1 = maximize channel )
  # This is short, simple , needs no channel setting, but very obtuse!
    -gamma 1,0,1

  # Threshold channels to zero
    -channel G -threshold 101% +channel

  # Threshold to maximum value then negate to zero
    -channel G -threshold -1 -negate +channel

  # Multiply with an appropriate primary/secondary color
  # The color specifies the channels to preserve!  'magenta' = 'red'+'blue'
    \( +clone +level-colors magenta \) -compose multiply -composite

  # Colorize specific channels to black
  # (0 = leave alone;   100% set from fill (black) )
    -fill black -colorize 0,100%,0

您能想到其他置零(或最大化)颜色通道的方法吗?这些方法我上面没有列出。——请发邮件告诉我。

颜色空间

到目前为止,我们一直专注于“sRGB”、“RGB”和“CMYK”颜色空间。这是因为这些颜色空间通常用于显示、打印和在文件中传统存储图像。但是,虽然这些颜色空间实用,但它们并不能代表我们人类实际看待世界的方式。我们的眼睛可能看到红色、绿色和蓝色波长,但我们的大脑将它们解释为:颜色色相(什么颜色)、灰度(颜色鲜艳程度)和强度(亮度/暗度)。正因为如此,许多颜色空间和颜色系统被开发出来,通常源于完全独立的需求。例如,画家开发了一种颜色系统(基于诸如群青之类的颜色来源)、阴影和色调。后来使用 RGB 的计算机系统需要更好的方法供用户选择或修改颜色,而不会过于计算密集。

基于色相的颜色空间

可能最著名的替代方案之一是基于循环色相的系统,它是作为 RGB 颜色的颜色选择界面而开发的。基本上,RGB 色彩立方体在 3 维空间中旋转,以便立方体的黑色-灰色-白色对角轴成为颜色空间的一个轴。这指定了颜色的暗或亮程度。这种变化的关键特征是从 RGB 值进行简单转换,这些值将原色均匀地分布在这个轴周围,从而形成一个从红色到绿色,再到蓝色,最后回到红色的循环色相。颜色距此轴的距离(径向)称为饱和度或彩度。
例如,让我们在将内置的“rose:”图像转换为“HSB”(色相、饱和度、亮度,也称为 HSV,其中 V 代表值)颜色空间后,分离其通道。

  magick rose: -colorspace HSB -separate separate_HSB_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
或者类似但并不完全相同的“HSL”(色相、饱和度、亮度)。

  magick rose: -colorspace HSL -separate separate_HSL_%d.gif
[IM Output] ==> [IM Output] [IM Output] [IM Output]
请注意,这两个颜色空间中的“色相”通道图像都是几乎纯黑色和白色的斑驳图案。这是因为色相实际上是循环的。也就是说,上面通道图像中的黑色和白色实际上都是“红色”色相的表示,并且细微的变化会导致色相从红色的一侧(产生白色)翻转到另一侧(产生黑色)。如果这是一个问题,您可以使用 调制运算符 旋转色相设置,以便红色由其他色相值表示。“HSL”和“HSB”之间的真正区别在于原色的亮度定义方式。但要看到这一点,我们最好查看颜色空间更实用的表示形式,使用色轮。如果您查看上面分离中的最后一个“亮度/明度”图像,您会发现“HSB”将强烈的(接近原色)“红色”视为几乎白色,而“HSL”将其视为更像是中等灰度的强度。

生成 HSL 色轮

上面从图像中分离出的原始通道仍然难以理解。为了更好地理解颜色空间,我们需要尝试查看它。颜色空间通常表示为圆形极坐标渐变,显示颜色空间的一部分。您可以生成单独的通道值图像,并组合这些图像以生成特定类型的图像,这些图像以其他方式难以生成。例如,这里我们生成完美的“HSL”色轮。

  magick -size 100x300 gradient: -rotate 90 \
          -distort Arc '360 -90.1 50' +repage \
          -gravity center -crop 100x100+0+0 +repage  angular.png
  magick -size 100x100 xc:white                     solid.png
  magick -size 100x100 radial-gradient: -negate     radial.png

  magick angular.png solid.png radial.png \
          -combine -set colorspace HSL \
          -colorspace sRGB colorwheel_HSL.png
[IM Output]
色相
[IM Output]
饱和度
[IM Output]
亮度
==> [IM Output]
HSL 色轮
灰度图像使用 sRGB 值作为线性渐变生成。因此,渐变看起来比应有的稍微暗一些。但是,这里重要的是输入图像中的值,而不是查看颜色空间。

另一方面,生成的图像虽然是在线性 RGB 颜色空间中生成的,但被保存为 sRGB 颜色空间,以确保浏览器和其他图像显示程序以视觉上效果良好的方式显示渐变。
还要注意,色相是一个“模数”值,在红色(色相值 = 0)处环绕。在进行图像处理时,这可能很麻烦,因为您有两个视觉上相同的红色,但在值方面却相距最大色相距离。这不是一个适合用于处理颜色差异的颜色空间。实际上,HSB 和 HSL 颜色空间的亮度/明度通道并不是非常有用,因为各种色相的处理方式并不相同。基本上它“均衡”了原色的强度。例如,将“黄色”色相旋转为“蓝色”色相会使非常明亮的颜色变得非常暗,反之亦然。有关更多详细信息,请参阅 HSL 缺点。建议谨慎使用。
还有一些颜色空间也使用相同的基于“六角锥”的色相系统。HSB、HCL 和 HCLp(感知 HCL)。以下是这四个“六角锥”颜色空间的色轮。

  magick angular.png solid.png radial.png \
          -combine -set colorspace HSL \
          -colorspace sRGB colorwheel_HSL.png
  magick angular.png solid.png radial.png \
          -combine -set colorspace HSB \
          -colorspace sRGB colorwheel_HSB.png
  magick angular.png solid.png radial.png \
          -combine -set colorspace HCL \
          -colorspace sRGB colorwheel_HCL.png
  magick angular.png solid.png radial.png \
          -combine -set colorspace HCLp \
          -colorspace sRGB colorwheel_HCLp.png
[IM Output]
HSL
[IM Output]
HSB
[IM Output]
HCL
[IM Output]
HCLp
请记住,上面显示的所有颜色都是在最大颜色饱和度下生成的。但是,“HSB”颜色空间将在最大亮度下生成原色(HSL 在一半强度下生成这些颜色)。正因为如此,只有当饱和度为零时才能生成白色。因此,您会得到完全饱和的颜色,而不是边缘周围的白色区域。“HCL”颜色空间使用相同的“六角锥”色相计算,但它调整“亮度”通道以使用颜色强度,而不是直接使用线性 RGB 值。因此,当使用“HCL”时,原色位于不同的强度级别,蓝色更靠近中心的黑色,红色更亮且更靠外。“HCL”颜色空间的 50% 强度区域不会产生强烈的颜色,而是生成更自然的柔和颜色。例如,以下是 HSL 和 HCL 颜色空间在 50% 强度下的饱和色相的比较。

  magick -size 100x100 xc:black \
          -fill white  -draw 'circle 49.5,49.5 40,4' \
          -fill black  -draw 'circle 49.5,49.5 40,30' \
          -alpha copy -channel A -morphology dilate diamond anulus.png
  magick hue_angular.png -size 100x100 xc:white xc:gray50 \
          -combine -set colorspace HSL -colorspace RGB \
          anulus.png -alpha off -compose Multiply -composite \
          anulus.png -alpha on  -compose DstIn -composite \
          -colorspace sRGB hues_HSL.png
  magick hue_angular.png -size 100x100 xc:white xc:gray50 \
          -combine -set colorspace HCL -colorspace RGB \
          anulus.png -alpha off -compose Multiply -composite \
          anulus.png -alpha on  -compose DstIn -composite \
          -colorspace sRGB hues_HCL.png
[IM Output]
HSL/HSB
[IM Output]
HCL
也就是说,并不是说“HCL”不包含纯色,它们只是不像在“HSL”颜色空间中那样被“强制”到一个公共平面中。特别是请注意,所有 HCL 色调都具有相同的 50% 强度(如所请求的),这与 HSL 颜色空间色调的结果不同。绿色可能是所有主要颜色中最接近 50% 强度的颜色,因此在 50% 色调中具有良好的响应。建议您将此颜色空间用于色相旋转,以保持图像中所有颜色的整体亮度。请参阅 在 HCL 颜色空间中调制 中的示例。HWB 颜色空间???

感知颜色空间

颜色空间“Lab”和“Luv”的设计使得它们可以完全分离图像的灰度强度和颜色成分。这与“RGB”和“sRGB”颜色空间不同。这使得颜色空间在您掌握窍门后更容易处理和修改。更具体地说,“Luv”的设计目的是“感知线性”。也就是说,颜色空间的一部分中的颜色微小变化看起来与颜色空间另一部分中的类似变化大致相同。这使得 Luv 颜色空间更适合于图像差异比较。这两个颜色空间非常相似,并且在处理图像时通常会产生类似的结果。在这里,我们分离了“Lab”和“Luv”颜色空间的通道,只是为了展示这两个颜色空间实际上有多么相似。

  magick rose: \( -clone 0 -colorspace LAB -separate +append \) \
                \( -clone 0 -colorspace LUV -separate +append \) \
          -delete 0 -append -set colorspace sRGB separate_lab_luv.png
[IM Output] ==> [IM Output] Lab


Luv
在下面LCH 色轮中,可以使用其圆柱形“LCHab”“LCHvu”变体看到“Lab”和“Luv”颜色空间的其他更好的示例。有关使用这些颜色空间的实用示例,请参阅 在 Lab 颜色空间中调整大小

基于 Lab 和 Luv 的颜色空间

HCL”颜色空间基于“LCHuv”颜色空间,它是“Luv”颜色空间的圆柱形表示,但亮度通道的公式更简单,以便在最大亮度下生成纯白色。为完整起见,这里提供了“Lab”和“Luv”颜色空间的圆柱形表示,分别称为“LCHab”和“LCHuv”。但是请注意,通道的顺序与上面显示的等效“HCL”颜色空间相反。

  magick radial.png solid.png angular.png \
          -combine -set colorspace LCHab \
          -colorspace sRGB colorwheel_LCHab.png
  magick radial.png solid.png angular.png \
          -combine -set colorspace LCHuv \
          -colorspace sRGB colorwheel_LCHuv.png
[IM Output]
亮度*
[IM Output]
彩度
[IM Output]
色相
==> [IM Output]
LCHab
[IM Output]
LCHuv
请注意,“LCH”颜色空间是“LCHab”的别名。在上面,您可以看到“LCHuv”存在一个不连续性,其中使用色轮过程设置了不切实际的颜色。图像的正常转换不会生成这些颜色。

scRGB 高动态范围颜色空间

Wikiepedia:  http://en.wikipedia.org/wiki/ScRGB

This is essentially a method of storing a High dynamic range color
(with negatives and up to 10 times linear RGB range) in a 16 bit integer,
with only 1/2 the color resolution of a normal 16-bit sRGB image.

As it is using 16bit integers it can be stored in image files formats that can
save such images (PNG, PPM, MIFF), though a color profile, or some other
method should be used to mark those images as holding scRGB colorspace data.

You would have to be very careful, with many image processing operators in
this colorspace as it has an 'offset' to allow it to handle negative numbers.
And while some operators like resize and distort can be used directly on this
colorspace, it is probably a better idea to use a HDRI version of ImageMagick,
and magick to linear RGB (with negatives), for more general image processing.

Examples and more information on using this colorspace would be good


替换图像中的颜色

ImageMagick 天然提供了许多选项来将特定颜色和近似匹配的颜色替换为另一种颜色。这在处理包含很少颜色图标和“位图”类型图像时非常有用,但在处理包含颜色阴影或抗锯齿边缘像素的图像时往往会失败。基本上,您需要记住颜色会被替换为单一的色调。因此,如果您替换一组或邻域的颜色,所有这些颜色都会被替换为一个特定的单一颜色,而不是替换为匹配的颜色范围。这并不是说无法进行阴影颜色替换,只是目前在没有大量工作的情况下,操作起来并不简单。即使这样,GIF 图像也不允许使用半透明,因此以这种方式替换颜色是控制 GIF 背景透明度的好方法(有关示例,请参见背景图案上的 GIF)另一个方面是,虽然您可以使用预定义颜色映射将所有“接近的颜色”映射到给定的颜色映射,但没有运算符可以对大量颜色进行一对一的直接映射到另一组完全不同的颜色。这是一个缺点,可能会在 ImageMagick 的未来版本中发生变化。有了这个警告,让我们看看 IM 提供的直接将一种特定颜色替换为另一种颜色。

替换特定颜色

"-opaque" 和 "-transparent" 运算符旨在将图像中的一种颜色替换为另一种颜色。例如,要将“蓝色”替换为“白色”,您可以使用如下命令...

  magick balloon.gif  -fill white -opaque blue   balloon_white.gif
[IM Output] ==> [IM Output]
基本上,任何“蓝色”的颜色都已被替换为当前的“-fill”颜色。但是,从 IM v6.2.7 开始,此运算符受“-channel”设置的限制。因此,要将颜色(例如蓝色)转换为透明,您需要指定一个“-channel”以包含 Alpha 通道以使颜色透明。您还需要确保图像启用了“蒙版”或Alpha 通道来保存透明度信息。

  magick balloon.gif   -alpha set  -channel RGBA \
                        -fill none -opaque blue   balloon_none.gif
[IM Output] ==> [IM Output]
由于将颜色替换为透明度是一种非常常见的操作,因此上述操作有其自身的特殊替换为透明度运算符“-transparent”。

  magick balloon.gif  -transparent blue   balloon_trans.gif
[IM Output] ==> [IM Output]
从 IM 版本 6.3.7-10 开始,这些运算符的“加号”版本反转了颜色选择。也就是说,不匹配给定颜色的颜色将被替换。例如,这里我将任何非纯黑色的颜色替换为白色,只保留图像的纯黑色边框。

  magick balloon.gif  -fill white +opaque black   balloon_borders.gif
[IM Output] ==> [IM Output]
这看起来似乎没什么,但是当您将其与模糊因子(见下文)结合使用时,它就会成为一个非常强大的工具。
在 IM v6.3.7-10 之前,逆向操作需要使用一些使用图像蒙版的技巧。基本上,您将要保留的颜色替换为透明,然后“-colorize”将所有其他颜色更改为所需颜色以创建叠加蒙版。然后将其叠加在原始图像上以“遮蔽”不匹配的颜色!

  magick balloon.gif \
          \( +clone -alpha set -transparent black \
             -fill white  -colorize 100% \) \
          -composite    balloon_mask_non-black.gif

[IM Output] ==> [IM Output]
如您所见,运算符的“加号”形式极大地简化了“非此颜色”替换操作。
有关更高级的替换技术,建议您查看背景移除
请注意,由于所有匹配的颜色(尤其是“模糊匹配的颜色”,见下文)都被替换为单一均匀的颜色,因此您不会获得彩色区域边缘的任何抗锯齿效果。并且您将丢失可能存在的任何阴影或其他阴影效果。这对任何非简单非卡通类图像的外观都会产生严重的不利影响。

这种类型的颜色替换并非针对实际的真实世界图像而设计,而是更多地用于图像蒙版效果。建议谨慎使用。
"-opaque" 颜色替换无法将颜色替换为平铺图案。它只会将颜色替换为另一个特定的单一颜色。但是“-draw”和“-floodfill”颜色替换方法都可以(见下文)。

使用图像中的颜色替换

您还可以使用绘制颜色替换根据图像本身存在的颜色而不是特定颜色重新着色图像。

  magick present.gif -fill red -draw 'color 0,0 replace' present_blue.gif
[IM Output] ==> [IM Output]
请注意,我从未指定要替换的颜色,仅指定了要替换的颜色位置。正是该位置的颜色用于“匹配”要填充的区域,无论该颜色是什么。您可以在上面的示例中看到颜色替换的问题,特定颜色可能会出现在您打算使用的其他位置,从而在我们上面的“当前”图像中产生一行红色像素。透明度也没有问题,尽管图像的一些内部部分也像上面一样变成了红色,也变得透明了……

  magick present.gif -alpha set -fill none \
                      -draw 'color 0,0 replace' present_none.gif
[IM Output] ==> [IM Output]
但是请注意,与“-opaque”和“-transparent”不同,绘制颜色替换不允许您反转要替换的“匹配颜色”。绘制还具有特殊的蒙版替换,其中仅替换填充颜色的透明度。也就是说,您可以使所有匹配的颜色透明或半透明,而无需实际更改像素本身的颜色。当然,前提是使用适当的文件格式。

  magick present.gif -alpha set -fill '#00000080' \
            -draw 'matte 0,0 replace' present_semi.png
[IM Output] ==> [IM Output]
当还指定了模糊因子时,这变得更有用。使用“-draw”的最大优势在于您还可以使用平铺图案替换颜色。例如..

  magick present.gif -tile pattern:right30 \
                -draw 'color 0,0 replace' present_tile.gif
[IM Output] ==> [IM Output]
有关更高级的替换技术,建议您查看背景移除

填充绘制

绘制颜色方法还为您提供了一种简单的方法来通过“泛洪填充”替换颜色。也就是说,您可以选择仅与图像中指定点“连接”或“附加”的颜色,而不是替换图像中所有匹配的颜色。指定的点不仅会指定起始(种子点),还会指定您尝试替换的颜色。

  magick present.gif -fill red -draw 'color 0,0 floodfill' present_fill.gif
[IM Output] ==> [IM Output]
请注意,未“附加”到 0,0 像素的红色区域未被替换。对于背景替换,这可能是一个问题,但解决方案同样简单。稍微扩展图像,以便泛洪填充可以从所有方向“泄漏”到图像中,然后在完成后删除多余的空间。

  magick present.gif -bordercolor white -border 1x1 \
          -fill red     -draw 'color 0,0 floodfill' \
          -shave 1x1               present_bgnd.gif
[IM Output] ==> [IM Output]
当然,您可以使用下面的模糊因子控制设置调整“匹配”的颜色,这对于JPEG图像尤其重要。

填充运算符

"-floodfill" 运算符的添加是为了使泛洪填充稍微容易一些,尤其是在您希望精确指定要替换的颜色时。这在使用模糊因子颜色匹配时尤其重要。但是请注意,如果种子点不在您要查找的颜色模糊因子匹配范围内,则“-floodfill”不会执行任何操作。这可以被认为是运算符的功能及其弊端。
建议为泛洪填充使用较小的模糊因子
或确保种子点与要查找的颜色完全匹配。
例如,添加已知颜色的边框以从边缘进行泛洪填充...

  magick present.gif -bordercolor white -border 1x1 \
          -fill red    -floodfill +0+0 white \
          -shave 1x1              present_floodfill.gif
[IM Output] ==> [IM Output]
这会将任何“白色”颜色替换为“红色”,这些颜色直接属于从 +0+0 开始的种子像素周围的区域,由于添加了边框,因此保证为“白色”。您还可以使用平铺图案进行泛洪填充。

  magick present.gif -bordercolor white -border 1x1 \
                -tile pattern:left30   -floodfill +0+0 white \
                -shave 1x1           present_pattern.gif
[IM Output] ==> [IM Output]
颜色”参数有时可能很麻烦,因为它必须与种子点的颜色匹配,否则将不会执行任何操作。但这也很有用,因为它将确保泛洪填充完全按照您的预期进行,而不是出现意外情况。例如,这里我尝试用各种颜色填充白色圆盘...

  magick disks.gif \
          -fill Red   -floodfill +30+50 white \
          -fill Green -floodfill +60+60 white \
          -fill Blue  -floodfill +10+40 white \
          floodfill_hit_miss.gif
[IM Output]
在这种情况下,只有“绿色”和“蓝色”泛洪填充操作“命中圆盘”(并填充它),而“红色”泛洪填充没有匹配圆盘,因此没有填充圆盘,而没有意外填充图像的背景。这也意味着,如果您已经填充了特定区域,以后的填充如果两个点命中该区域,将不会“重新填充”该区域。这可以节省大量时间。您可能还想查看条件膨胀,它表示来自图像中多个“种子”点的较低级别的泛洪填充操作。

模糊因子 - 匹配相似/多种颜色

如前面的示例所示,仅选择单一颜色进行替换的总体结果通常不是很好。由于抗锯齿,实心颜色的边缘或区域通常在边缘混合了颜色(有关更多信息,请参见抗锯齿)。因此,如果可能,您应该避免直接颜色替换。例如,这里我采用看起来像简单的黑白“奶牛”并尝试将其变成红色的奶牛。

  magick cow.gif -fill red -opaque black  cow_replace_red.gif
[IM Output] ==> [IM Output]
如您所见,只有“黑色”区域的中心部分实际上变成了红色。这是因为,虽然图像看起来是黑白的,但它实际上是灰度图像,几乎所有边缘都是各种深浅的灰色。也就是说,它们的色彩并非完全纯黑色。模糊因子(“-fuzz”)表示使用图像使用的任何颜色空间,在颜色之间进行多维球面距离的“相似性”匹配。好吧,让我们用简单的英语来尝试一下。您有一个特定的颜色。如果这些颜色之间的差异小于模糊因子设置,则另一个颜色将被视为与要查找的颜色相同。模糊因子越大,“接近”的颜色就越多会匹配并被替换。因此,让我们在奶牛图像上尝试一下,以便不仅将纯黑色,而且将近黑色颜色也转换为红色。


  magick cow.gif -fuzz 40%  -fill red -opaque black  cow_replace_fuzz.gif
[IM Output] ==> [IM Output]
如您所见,我们现在已将图像中所有“暗色”像素替换为红色。但结果仍然很糟糕,边缘带有灰色的色调,并且有强烈的锯齿效应。直接颜色替换对于此图像并不是一个好的解决方案,即使您可以使用较大的“模糊因子”使其工作。请参阅按颜色调整色阶中的示例,了解此图像的理想解决方案。对于尝试用透明度替换背景颜色的图像,此问题更加严重。您基本上会在该背景颜色上的对象周围形成一个“光晕”。这非常难以解决,并且此类问题将在背景移除中详细介绍。哪些操作使用模糊因子-fuzz” 运算符会影响几乎所有比较图像中特定颜色的运算符。这包括:“-opaque”、“-transparent”、“-floodfill”、“-trim”、“-deconstruct”、“-draw 'color'”、“-draw 'matte'”,以及可能的其他运算符。它还会影响 GIF 的“-layers OptimizeTransparency”和“-compose ChangeMask”处理。它还会影响“magick compare”的结果,特别是“-metric AE”或绝对误差像素计数。

模糊因子距离

-fuzz”设置实际上是一种颜色“距离”设置。任何在给定距离内的颜色,都会与正在查找的颜色匹配,即使它不是完全匹配。值“200”表示在当前使用的 IM 的颜色深度中 200 个颜色单位的距离。对于 IM Q16(颜色存储的 16 位质量),这相当小;对于 IM Q8,这非常大,并且会导致许多颜色相互匹配。
例如,这里我将所有在 30,000 个颜色单位(对于 IM Q16)内的颜色(以“blue”为中心)更改为白色。在我的 Q16 ImageMagick 程序中,这大约代表了从“blue”到“navy”(半暗蓝色)的距离。

  magick colorwheel.png \
          -fuzz 30000 -fill white -opaque blue \
          opaque_blue.jpg
[IM Output]
为了更容易理解,我这里反转了匹配的颜色,将不匹配的颜色变为白色。

  magick colorwheel.png \
          -fuzz 30000 -fill white +opaque blue \
          opaque_blue_not.png
[IM Output]
如果您的 IM 版本早于 6.3.7-10(“-opaque”运算符的“加号”形式添加的版本),您可以使用此遮罩方法反转颜色匹配的结果…

  magick colorwheel.png \
          \( +clone  -fuzz 30000 -transparent blue \
             -channel RGB +level-colors white +channel \) \
          -composite   opaque_blue_inv.png
[IM Output]
或者这种方法仅将所有修改限制为“alpha 通道”,以便所有原始颜色保持不变。也就是说,您根据颜色选择创建一个反转的遮罩,以便使所有未选中的颜色完全透明。它们仍然存在,只是透明的!

  magick colorwheel.png -fuzz 30000 -transparent blue \
          -channel A -negate +channel   opaque_blue_inv_alpha.png
[IM Output]
这些替代方法的一个优点是,您可以扩展它们以生成“非多种颜色”技术。您需要做的就是在反转遮罩之前将更多颜色添加到要设置为透明的颜色列表中,并可能移除反转的透明度。

  magick colorwheel.png \
          -fuzz 25000 -transparent blue -transparent red -transparent lime \
          -channel A -negate +channel \
          -background white -alpha remove   opaque_multi_inv.png
[IM Output]

顺便说一句,在使用 Q8 编译设置的 IM 中,“-fuzz”因子为 256(28)将使颜色“black”和“blue”等效。对于使用 Q16 设置的 IM,此数字为 65536(216)。

要使“blue”和“red”颜色匹配,此数字必须乘以 2 的平方根,对于 IM Q8 为 362,对于 IM Q16 为 92682。

要使所有颜色匹配(例如颜色“black”和“white”),您需要乘以 3 的平方根。换句话说,对于 IM Q8,模糊因子设置为 444,对于 IM Q16,设置为 113512。
使用“感知”色彩空间(如“LAB”或“LUV”)可能可以定义更好、更真实的颜色距离。只需在执行模糊颜色匹配之前将图像转换为该色彩空间即可。这将使纯蓝色和黑色等颜色更接近,黄色和白色更接近,而不是在“sRGB”或线性“RGB”色彩空间中。
如您从上述公式中看到的,直接颜色距离绝对不是设置要使用的模糊因子的好方法,因为它还取决于使用的确切编译时质量设置。将“-fuzz”因子设置为百分比,使其使用起来更加简单。在这种情况下,“100%”表示一个足够大的模糊因子以覆盖所有颜色。也就是说,它表示从“black”到“white”的颜色距离,跨越 RGB 颜色立方体的 3 维对角线。
这里我们用白色替换任何在白色到黑色距离的 90% 内的颜色。这应该会导致只有靠近“black”的最后 10% 的颜色保留在图像上,因为黑色位于 RGB 颜色立方体的相对侧。

  magick colorwheel.png -fuzz 90% -fill white -opaque white  opaque_w90.jpg
[IM Output]
请注意,此 90% 代表 RGB 颜色立方体中围绕“white”的颜色球体。但是,这与替换不在黑色 10% 球体内的颜色并不相同。

  magick colorwheel.png -fuzz 10% -fill white +opaque black  opaque_k10.jpg
如您所见,靠近黑色的 10% 颜色球体比选择围绕白色的 90% 颜色球体更加均匀。考虑一下以立方体白色角为中心的较大球体是如何填充该立方体的。然后考虑一下以黑色角为中心的较小球体,您将能够理解这两个图像之间的区别。
[IM Output]
-fuzz”因子为 100% 等于 RGB 颜色立方体中从“black”到“white”的距离。由此我们可以计算出大约 57.7% 的百分比是从“black”到“blue”的距离,而 81.6% 的百分比是从“blue”到“red”的距离,或者从这两个颜色中的任何一个到“white”的距离。

总之,任何大于约 25% 的值(略小于 RGB 中从“blue”到“navy blue”的距离)都表示颜色变化非常大。
为了更清楚地展示颜色距离,让我们围绕蓝色使用逐渐增大的模糊因子百分比…

  magick colorwheel.png -fuzz 10% -fill white -opaque blue opaque_b10.jpg
  magick colorwheel.png -fuzz 25% -fill white -opaque blue opaque_b25.jpg
  magick colorwheel.png -fuzz 57% -fill white -opaque blue opaque_b57.jpg
  magick colorwheel.png -fuzz 81% -fill white -opaque blue opaque_b81.jpg
  magick colorwheel.png -fuzz 95% -fill white -opaque blue opaque_b95.jpg
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
由此您可以清楚地看到,最远离“blue”的颜色不是“black”或“white”,而实际上是“yellow”在 RGB 色彩空间中最远。另请注意,81% 的颜色差异将刚好错过匹配纯“red”颜色,但是虽然纯红色不匹配其他红色(不包括橙红色),但确实匹配。也就是说,再次由于颜色匹配的“球形”特性。寓意是,您可能最好使用多个小的“-fuzz”因子匹配或较小的“反向匹配”,而不是单个较大的值。这里我们将图像中的颜色与另一种颜色(“近乎完美的灰色”)进行比较,随着“模糊因子”的增加,将相似的颜色更改为相同的灰色。

  magick colorwheel.png -fuzz 25% -fill gray50 -opaque gray50 opaque_g25.jpg
  magick colorwheel.png -fuzz 30% -fill gray50 -opaque gray50 opaque_g30.jpg
  magick colorwheel.png -fuzz 35% -fill gray50 -opaque gray50 opaque_g35.jpg
  magick colorwheel.png -fuzz 45% -fill gray50 -opaque gray50 opaque_g45.jpg
  magick colorwheel.png -fuzz 51% -fill gray50 -opaque gray50 opaque_g51.jpg
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
如您所见,色轮图像中的颜色刚刚开始在模糊因子略低于 30% 时匹配,并缓慢增加,直到在 45% 时除最极端的颜色外所有颜色都消失了。在 51% 时,图像中的所有颜色都与近乎完美的灰色匹配。您看到的是 RGB 颜色在 3 维空间中排列成立方体的方式的结果。“色轮”图像仅包含“完全饱和的颜色”,这基本上意味着位于 RGB 颜色立方体外表面上的所有极端颜色。但是,完美的灰色位于立方体的中心,与所有“饱和颜色”都相距甚远。因此,直到您达到 28% 的大模糊因子,立方体面中间的颜色才会开始匹配。随着模糊因子变大,越来越多的颜色将匹配,直到只剩下颜色立方体极端角的颜色。在 50% 左右,角颜色也将开始匹配,因此在 51% 时,每个不透明的 RGB 颜色都将匹配。

模糊因子和透明颜色

当匹配涉及透明和半透明颜色时,使用“-fuzz”因子会变得更加复杂。例如,这里我在图像上创建了从黑色到白色的渐变,然后垂直添加透明渐变。然后,我对完美的灰色(即 50% 灰色)进行模糊颜色匹配。在后面的图像中,我使要匹配的颜色变得更透明,直到它完全透明,但是模糊因子保持不变,为 20%。

  magick -size 100x100 gradient: \( +clone -rotate 90 \) +swap \
          -compose CopyOpacity -composite  trans_gradient.png
  magick trans_gradient.png -channel RGBA \
          -fuzz 20% -fill Gray50 -opaque 'GrayA(50%,1.0)' fuzz_trans_100.png
  magick trans_gradient.png -channel RGBA \
          -fuzz 20% -fill Gray50 -opaque 'GrayA(50%,.75)' fuzz_trans_75.png
  magick trans_gradient.png -channel RGBA \
          -fuzz 20% -fill Gray50 -opaque 'GrayA(50%,.40)' fuzz_trans_40.png
  magick trans_gradient.png -channel RGBA \
          -fuzz 20% -fill Gray50 -opaque 'GrayA(50%,0.0)' fuzz_trans_00.png

[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output]
请注意,上面使用“-channel RGBA”不是为了颜色匹配,而是为了指定要“填充”的颜色通道。也就是说,如果没有它,上面仍然会匹配相同的颜色,但灰色“填充”将保持半透明,而不是设置为不透明的灰色。如果您想匹配所有颜色,无论其透明度如何,则需要关闭图像的透明通道,至少暂时如此。您可以在之后再次打开它,尽管您的填充颜色将再次具有与原始颜色相同的透明度。在第一个图像中,使用完全不透明的灰色(alpha='1.0')进行匹配,您将获得所有接近不透明的灰色的非常球形的匹配。但是,随着要匹配的颜色变得更半透明,匹配的半透明颜色的数量似乎会变得更大,直到完全透明的灰色将匹配任何接近透明的颜色。发生的情况是,随着透明度的增加,半透明颜色之间的距离减小。两个颜色越透明,与它们的不透明对应物相比,这些颜色就越接近。当两个颜色都完全透明时,这两个颜色将被视为完美或“0”距离匹配。需要注意的另一件事是(截至 IM v6.6.6-4),完全透明的颜色(灰色或其他颜色)的距离纯粹是颜色透明度(alpha 值)的函数。上面最后一个图像匹配了所有在 20% 以内接近完全透明的像素,而不管实际颜色如何。
这也意味着使用完全透明的颜色(如“none”)的大模糊因子可以用来匹配所有或几乎所有半透明颜色。例如…

  magick trans_gradient.png -channel RGBA \
          -fuzz 95% -fill Gray50 -opaque None \
          -alpha off  fuzz_trans.jpg
[IM Output]
请注意,上面只有前 5% 的接近不透明的颜色没有匹配,而所有其他半透明的颜色都变成了灰色。“-alpha off”最终消除了图像中最后一点半透明度。因此,“-channel RGBA”设置实际上并不需要,但建议为了完整性起见。此示例基本上等效于 alpha 通道的阈值,然后在下面添加灰色底色(使透明颜色变为灰色)

在 IM v6.6.6-4 之前,模糊颜色匹配没有完全平等地匹配完全透明色与不透明色。事实上,黑色比白色更接近匹配。因此,最后一个示例将失败。有关更多详细信息,请参见 模糊距离和透明颜色错误
更糟糕的是,在 IM v6.2.6-2 之前,模糊颜色匹配没有将所有完全透明的颜色视为相同的颜色。也就是说,完全透明的黑色(也称为“无”)与完全透明的白色(或颜色“#FFF0”)不同,即使它们都是完全透明的。

建设中
Color maths (get the average of two or more colors)....

  Example Averaging two colors... Say '#000000'  and  '#DDDDDD'

  Generally the colors are added to images, and the result output as a
  single pixel 'txt:-' image, which which the color can be extracted.

  * use -resize to merge the colors

      magick -size 2x1 xc:'#000000' -fill '#DDDDDD' \
              -draw 'point 0,0'  -resize 1x1  txt:-

  * Use -evaluate-sequence mean on them!

      magick -size 1x1 xc:'#000000' xc:'#DDDDDD' \
              -evaluate-sequence mean  txt:-

    Or for a lot of colors you can use the 'Box' resize filter
      magick rose: -filter Box -resize 1x1\! txt:
      # ImageMagick pixel enumeration: 1,1,255,RGB
      0,0: (145, 89, 80) #915950

  * Use -fx to apply whatever formula you want

      magick -size 1x1 xc:'#000000' xc:'#DDDDDD' \
              -fx '(u+v)/2'  txt:-

  With an ImageMagick API the results can be more directly retrieved from the
  image.