⚠️ 这是一个非官方翻译网站,与 ImageMagick Studio LLC 无关。准确信息请参阅原文(https://usage.imagemagick.org/canvas/index.html)

ImageMagick 示例 -- 画布创建

画布在 ImageMagick 中用作绘图的起始图像、作为透明叠加图像的背景,甚至作为一般图像处理的一部分。画布可以是单一颜色、具有多种颜色,甚至可以是小图像的图块。在这里,我们将介绍一些可用于生成不同画布图像的技术。


单色画布

直接生成

生成特定颜色和尺寸的画布非常容易。指定“[-size](https://imagemagick.org/command-line-options/#size)”(如果没有指定尺寸,则默认为“1x1”)并使用“canvas:”生成指定颜色的画布。如果未指定颜色,将生成“white”(白色)的画布。 例如,这里我们生成一个颜色为“khaki”的画布。 |

  magick -size 100x100 canvas:khaki  canvas_khaki.gif

[IM 输出]
更常见的是,使用缩写形式“xc:”(意思是“X Constant Image”)。我通常用这个。例如,这是一个带有 X 窗口颜色“wheat”的图像。 |

  magick -size 100x100 xc:wheat  canvas_wheat.gif

[IM 输出]
借助一些灵活的图像读取修改器,你可以把纯色画布图像指定为单个参数。这种技术让你能把特定大小和颜色的“xc”画布图像,作为许多 ImageMagick 脚本的单个“输入图像”参数。 |

  magick 'xc:Salmon[100x100!]'  canvas_salmon.gif

| “!” 是必需的,因为这些数字是调整尺寸值;否则如果不是正方形,就得不到请求的尺寸。
---|---
[IM 输出]
如果你已经创建了画布但需要不同的颜色,则可以将其替换为“[-opaque](https://imagemagick.org/command-line-options/#opaque)”运算符。 |

  magick canvas_khaki.gif -fill tomato -opaque khaki canvas_tomato.gif

[IM 输出]
你还可以从现有图像中获取单个像素并将其缩放到所需的画布大小。使用“[-scale](https://imagemagick.org/command-line-options/#scale)”可以简单快速地调整单个像素的大小。 在这里,我们从内置的“rose:”图像中提取玫瑰色。 |

  magick rose: -crop 1x1+40+30 +repage -scale 100x100\! canvas_rose_red.gif

[IM 输出]

创建相同大小的图像

使用 ImageMagick 的最基本方法之一,是生成与现有图像大小相同的画布。这可以通过把现有图像转换为所需画布、同时保留原图大小来实现。一般来说,需要保留的不只是图像大小,还包括图像的所有元数据,例如标签、注释、颜色配置文件、时间延迟,以及保存时的压缩和位深度。如果你想把这些信息标注到新清空的画布上,或者计划把原图叠加到新画布上并需要保留这些信息,这些元数据就可能很重要。当然,IM 提供了许多实现方式,通常是使用各种图像操作时产生的副作用。只有少数方法明确用于把图像清除为单色。 左侧是一张测试图像。不用担心我实际是怎样生成这张图像的,这对本练习并不重要。我特意让它包含多种颜色、透明度和其他特性,以便在使用时充分考验 IM。 如果你真的对生成这张图像所用的命令感兴趣,可以查看我用来创建它的专用脚本“generate_test”。 [IM 输出]

叠加特定颜色

IM 从 v6.4.2-1 开始,“[+level-colors](https://imagemagick.org/command-line-options/#level_colors)”可以指定为单一颜色,无需逗号来设置所有颜色。 |

  magick test.png  -alpha Opaque +level-colors Sienna  color_levelc.gif

[IM 输出]
请注意,我在添加颜色之前(或之后)使用“[-alpha](https://imagemagick.org/command-line-options/#alpha)”运算符将透明度设置为有用的状态。或者,你可以使用“-channel All”,以便重置颜色的操作也会设置透明度通道。另一种旧技术是使用“[-colorize](https://imagemagick.org/command-line-options/#colorize)”用完全不透明的值覆盖填充颜色。但在 IM v6.7.9 之前,这不会改变原始图像的 alpha 通道,因此你可能需要首先使用“[-alpha](https://imagemagick.org/command-line-options/#alpha) [Off](masking.html#alpha_off)”禁用 alpha 通道,或者使用“[-alpha](https://imagemagick.org/command-line-options/#alpha) [Opaque](masking.html#alpha_off)”使其不透明。但是,你无需这样做也可以获得相同的结果。 |

  magick test.png -alpha off -fill Chocolate -colorize 100%
color_colorize.gif

| [-alpha](https://imagemagick.org/command-line-options/#alpha) [Off](masking.html#alpha_off)”(或旧版等价形式“[-alpha off](https://imagemagick.org/command-line-options/#matte)”)只会禁用 alpha 通道。如果之后再将它 On,原先保留的 alpha 通道会被恢复。在 IM v6.7.9 之前,使用“[-colorize](https://imagemagick.org/command-line-options/#colorize)”时 alpha 会被保留。
---|---
[IM 输出]
IM 从 v6.4.3-0 开始,你可以使用“[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)”运算符将一个点设置为所需的颜色并将其分布在图像上。几乎任何着色方法都可以使用(参见下面的颜色稀疏点)。 |

  magick test.png  -alpha Off \
          -sparse-color Voronoi '0,0 Peru' color_sparse.gif

[IM 输出]
更常见的方法是使用“[-draw](https://imagemagick.org/command-line-options/#draw)”直接将当前图像中的所有颜色重置为当前“[-fill](https://imagemagick.org/command-line-options/#fill)”颜色。 |

  magick test.png -fill Tan -draw 'color 0,0 reset' color_reset.gif

[IM 输出]
这是 ImageMagick 版本 5 中推荐的方法。
上述所有“简单”方法的主要问题是,它们都不能直接把图像重置为当前的“[-background](https://imagemagick.org/command-line-options/#background)”颜色。下一组方法利用 alpha 合成,强制各种运算符把图像替换为所需颜色。这些多图像方法适用于使用“[-compose](https://imagemagick.org/command-line-options/#compose)”的运算符。 例如,你可以使用“[-flatten](https://imagemagick.org/command-line-options/#flatten)”(见平铺到背景示例)创建使用“[-background](https://imagemagick.org/command-line-options/#background)”颜色的画布。 |

  magick test.png   -background Wheat \
            -compose Dst   -flatten   color_flatten.gif

[IM 输出]
上面使用“[Dst](compose.html#Dst)”合成方法,只读取背景画布并忽略原图像的像素颜色。 如果你只想保留原图像的元数据(例如注释或标签数据),但把图像本身替换为特定颜色和尺寸的画布图像,那么“[-extent](https://imagemagick.org/command-line-options/#extent)”运算符(见 Extent,直接调整图像尺寸)可能是最佳方案。这里同样使用“[Dst](compose.html#Dst)”合成方法,让它忽略原图像的像素数据,只使用“[-background](https://imagemagick.org/command-line-options/#background)”颜色。 |

  magick test.png   -background LemonChiffon \
            -compose Dst   -extent 100x100   color_extent.gif

[IM 输出]
或者,你可以使用“[-border](https://imagemagick.org/command-line-options/#border)”(请参阅添加边框)并使用“[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)”作为颜色源。 |

  magick test.png   -bordercolor Khaki \
            -compose Dst   -border 0   color_border.gif

[IM 输出]
最后一项技术还有一个额外好处:它允许你相对于原始图像尺寸稍微扩大画布。 | [-border](https://imagemagick.org/command-line-options/#border)”画布生成方法不适用于 6.1.4 之前的 IM 版本。此前,“[-border](https://imagemagick.org/command-line-options/#border)”运算符生成的背景不是简单的纯色,而是一个被边框颜色包围的黑色画布,并不实用。
---|---
[FX, DIY Operator](transform.html#fx)”运算符提供了一种更灵活(但速度慢得多)的画布生成方法。默认情况下“[-fx](https://imagemagick.org/command-line-options/#fx)”不会触及透明度通道,因此你还必须禁用输入图像的透明度通道。 |

  magick test.png -alpha off -fx Gold  color_fx_constant.gif

[IM 输出]
[-fx](https://imagemagick.org/command-line-options/#fx)”运算符还允许你进行一些较小的颜色计算。例如,70% 深金色怎么样... |

  magick test.png -alpha off -fx "Gold*.7"  color_fx_math.gif

[IM 输出]
所有上述技术都允许填充完全不透明的颜色以及半透明的颜色。但是,最好事先确保你的图像具有透明度通道。 例如,我们将创建一个半透明红色的画布。然而,当我将其叠加在该网页的“蓝色”背景上时,它变成暗紫粉色。 |

  magick test.png -alpha set -fill '#FF000040' -draw 'color 0,0 reset' \
            color_semitrans.png

[IM 输出]
另请注意,使用 "[-fx](https://imagemagick.org/command-line-options/#fx)" 运算符处理透明度时,需要设置 "[-channel](https://imagemagick.org/command-line-options/#channel)" 来修改全部四个 'RGBA' 颜色通道。

用选取的颜色清空图像

也可以使用原始图像中的颜色来消隐图像,但这有点棘手。当你想要使用特定像素作为“背景颜色”时,这是一种有用的技术。例如,像素 0,0 是一个热门候选。 [IM 输出] 以下示例在消隐图像时从内置玫瑰图像(如左侧所示)的各个像素中选取颜色。最明显(但最慢)的方法是简单地使用“[FX, DIY Operator](transform.html#fx)”来选择用于颜色消隐的像素。 |

  magick rose: -fx 'p{0,0}'  color_pick_fx.png

[IM 输出]
但是,可以通过只选择一次像素来加快速度。做法是把 fx 表达式用作 稀疏颜色 的参数。虽然乍一看可能不简单,但速度要快得多。 |

  magick rose: -sparse-color voronoi '0,0 %[pixel:p{40,30}]'
color_pick_sparse.png

[IM 输出]
另一种更复杂的方法是剪掉单个像素并将其平铺在图像上。这使用了稍后在使用内存中已存在的图像进行平铺中详细解释的技术。 |

  magick rose: \( +clone -crop 1x1+64+22 -write MPR:pixel +delete \) \
          -fill mpr:pixel  -draw 'color 0,0 reset' \
          color_pick_draw.png

[IM 输出]
|

  magick rose: -set option:distort:viewport '%wx%h+0+0' \
          -crop 1x1+10+25 +repage     -distort SRT 0 \
          color_pick_distort.png

[IM 输出]

其他画布技巧

还有许多其他方法可以制作非常特定颜色的画布,但它们要微妙得多。因此,如果你没有正确注释,你可能会在几个月或几年后查看你的 IM 脚本,并且不知道它实际上在做什么。尽管我们不推荐这些技术,但它们对于了解你是否使用旧的、灵活性较差的 IM 版本很有用。 黑色画布。使用“-threshold”,然后禁用透明度通道。 传统上,你可以按如下方式创建黑色画布:

  magick test.png -threshold 100% -alpha off  black_threshold.png

[IM 输出]

通过为“-level”运算符中的“黑”点和“白”点指定相同的参数可以实现相同的效果。

  magick test.png -level 100%,100% -alpha off  black_level.png

[IM 输出]

“-fx”运算符提供了一种更直接的方法,通过将所有像素清除为零来创建黑色画布。但是,你还需要重置 alpha 通道以使其完全不透明。

  magick test.png  -fx 0 -alpha off   black_fx.png

[IM 输出]

然而,这个使用“-evaluate”的版本应该更快,特别是对于大图像。

  magick test.png  -evaluate set 0  -alpha off  black_evaluate.png

[IM 输出]

你还可以借助“-gamma”运算符使图像全黑。

  magick test.png  -gamma 0  -alpha off  black_gamma.png

[IM 输出]

[IM 输出] 一种不太明显的方法,是用太少的颜色级别对图像进行“色阶分离”,结果只剩下一种颜色:黑色。 |

  magick test.png  -posterize 1 -alpha off black_posterize.png

alpha运算符。你可以使图像完全透明,然后“extract”(提取)该图像的蒙版。

  magick test.png  -alpha transparent -alpha extract  black_alpha.png

[IM 输出]

白色画布。传统上这也使用“-threshold”。但是,该值必须为负数,以确保所有颜色在 IM 的所有版本中映射为白色。

  magick test.png  -threshold -1 -alpha off   white_threshold.png

[IM 输出]

通过在“-level”运算符中为“黑”点和“白”点指定相同的参数可以实现相同的效果。

  magick test.png -level -1,-1 -alpha off  white_level.png

[IM 输出]

当然,你也可以直接使用“-fx”运算符设置像素值。

  magick test.png -fx 1.0 -alpha off  white_fx.png

[IM 输出]

然而,这个使用“-evaluate”的版本应该更快,特别是对于大图像。

  magick test.png  -evaluate set 100%  -alpha off  white_evaluate.png

[IM 输出]

[IM 输出] 或者对某些黑色画布生成方法取反。 |

  magick test.png -posterize 1 -alpha off -negate  white_posterize.png

alpha运算符。你可以使图像完全不透明(无透明度),然后使用“extract”(摘录)遮盖该图像。

  magick test.png  -alpha opaque -alpha extract  white_alpha.png

[IM 输出]

透明画布。也许你最常想从现有图像生成的画布,就是透明画布。你可以在其上绘制和添加内容,调整到想要的效果,然后再把它叠加回原始图像上。最快、最简单的方法是使用“-alpha transparent”运算符(IM v6.4.3-7 中加入),让 IM 直接把图像清除为透明。

  magick test.png  -alpha transparent trans_alpha.png

但是,这是最近添加的,因此可能尚未广泛使用。 [IM 输出]

“Clear”alpha 合成运算符允许你使用任何重叠图像(在本例中为单个像素“null:”)创建完全透明的“黑色”画布。这是因为叠加的图像被忽略。

  magick test.png  null: -alpha set -compose Clear -composite -compose Over \
          trans_compose.png

[IM 输出]

这里我们使用“-draw matte”运算符将遮罩(透明度)通道的值替换为当前“-fill”颜色设置的透明度值。在这种情况下,使其完全透明。

  magick test.png -alpha set -fill none  -draw 'matte 0,0 reset'
color_matte.png

[IM 输出]

你还可以使用“-fx”运算符更直接地执行此操作。

  magick test.png -alpha set -channel A -fx 0 +channel  trans_fx.png

[IM 输出]

当然,这个使用“-evaluate”的版本应该更快,特别是对于大图像。

  magick test.png  -alpha set -channel A -evaluate set 0 +channel \
          trans_evaluate.png

[IM 输出]

使图像完全透明的另一种方法是使用“-threshold”,但将效果限制为仅透明度通道。

  magick test.png -channel A -threshold -1 +channel trans_threshold.png

[IM 输出]

实际上,在这种情况下,从数学上说我们处理的是 'matte' 通道:用阈值把它设为最大值,而不是像 "-fx" 运算符那样设为零。这就是上面使用 '-1',而不是类似 101% 的值的原因。在上面许多图像结果中,原始图像的 RGB 颜色仍然存在,只是被变成了透明。例如,这里我们读取上面的一个图像,并让 IM 关闭图像中的 matte/alpha 通道,以便再次显示这些颜色。 |

  magick trans_fx.png -alpha off  trans_fx_alpha_off.jpg

但请注意,并非所有图像文件格式或除少数图像操作外的所有图像操作都会保留部分透明的 RGB 颜色,这些颜色仍然存在于结果图像中。 [IM 输出]
如前所述,也值得再说一遍:上面许多方法都依赖图像已经具有 alpha 通道。如果没有,可以用“[-alpha](https://imagemagick.org/command-line-options/#alpha) [On](masking.html#alpha_on)”添加一个;不过在这种情况下,你也可以直接使用“[-alpha](https://imagemagick.org/command-line-options/#alpha) Transparent”运算符。示例见控制图像透明度。 其他画布着色除了使用特定颜色之外,只有“-gamma”运算符真正足够灵活,能够生成任意主色/副色的画布。基本做法是使用 0 把某个通道清零,用 -1 最大化某个通道值。 例如,这里我生成一个黄色画布…… |

  magick test.png  -gamma -1,-1,0  -alpha off  yellow_gamma.png

[IM 输出]
IM 从 v6.4.2 开始,你还可以使用“[+level](https://imagemagick.org/command-line-options/#level)”运算符为所有颜色通道设置特定的灰度级。 |

  magick test.png  +level 40%,40%  -alpha off  grey_level.png

[IM 输出]


颜色渐变

正如我们在上面看到的,纯色画布很容易创建。但有时你想要一些更有趣的东西。 一种非常有用的图像创建运算符是“gradient:”。例如…|

  magick -size 100x100 gradient:  gradient.jpg

[IM 输出]
如你所见,默认情况下“gradient:”创建的图像顶部为白色,底部为黑色,并且在图像的整个高度上具有平滑的灰色阴影。但不仅仅是灰度渐变,你还可以指定一种或两种颜色来产生不同颜色的渐变

  magick -size 100x100  gradient:blue              gradient_range1.jpg
  magick -size 100x100  gradient:yellow            gradient_range2.jpg
  magick -size 100x100  gradient:green-yellow      gradient_range3.jpg
  magick -size 100x100  gradient:red-blue          gradient_range4.jpg
  magick -size 100x100  gradient:tomato-steelblue  gradient_range5.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

请注意,如果只给出一种颜色,第二种颜色会是“white”或“black”,取决于哪一种与给定颜色的色距最大。因此,“blue”会生成“blue-white”渐变,而“yellow”会生成“yellow-black”渐变。“red-blue”渐变在中间有一条暗得多的紫色带。这种变暗是由较暗的非线性 sRGB 色彩空间造成的,尤其在强原色上更明显。更多细节见处理真实图像。 | _“gradient:”目前只理解 sRGB 色彩空间中的颜色表示。因此,你不能在线性 LAB 色彩空间中使用“red-blue”颜色生成更亮、更正确的“紫色”渐变。

这也意味着你无法使用 HSV 色彩空间生成多色“彩虹”渐变。

不过,可以相对容易地“变通”生成这类渐变。见下方其他色彩空间中的渐变
---|---
| _渐变目前无法指定其他角度,也无法涉及两种以上的颜色。不过,由于这种能力是 SVG 渐变不可或缺的一部分,这种情况很可能会改变,渐变选项也会得到重大改进。

---|---
一些特别好的渐变包括…… |

  magick -size 10x120  gradient:snow-navy          gradient_ice-sea.jpg
  magick -size 10x120  gradient:gold-firebrick     gradient_burnished.jpg
  magick -size 10x120  gradient:yellow-limegreen   gradient_grassland.jpg
  magick -size 10x120  gradient:khaki-tomato       gradient_sunset.jpg
  magick -size 10x120  gradient:darkcyan-snow      gradient_snow_scape.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]
| _IM 从 v6.3.1 开始,生成渐变的算法现在生成水平均匀的颜色。也就是说,图像每行中的所有像素都被分配相同的颜色。即每行一种颜色。

在此版本之前,“gradient:”运算符忽略图像宽度并分配下一个颜色增量,一次一行,从图像的左上角到右下角。

结果,渐变主要仍是垂直渐变,就像现在一样,但并不完美。通常只有在测试图像,或用于图像映射等特殊场景时,这一点才重要。

_
---|---

渐变的行为可能会受到以下定义的影响:

gradient:angle=角度(以度为单位) 对于线性渐变,指定从 color1 到 color2 的渐变方向,以北(顶部)为正顺时针方向。对于径向渐变,指定渐变从其正常 X-Y 方向的正顺时针旋转。 ImageMagick 6.9.2-5 版本支持。
gradient:bounding-box=WxH+X+Y 将渐变限制为大于或小于图像尺寸的区域。如果边界框定义的区域小于图像,则 color1 将成为背景颜色。 ImageMagick 6.9.2-5 版本支持。
gradient:center=x,y 指定径向渐变的中心点坐标。默认为图像的中心。 ImageMagick 6.9.2-5 版本支持。
gradient:direction=value 指定线性渐变朝向上/下/左/右或对角角落的方向。可选值为:NorthWest, North, Northeast, West, East, SouthWest, South, SouthEast。ImageMagick 6.9.2-5 版本支持。
gradient:extent=value 指定以图像中心为中心的径向渐变形状。可选值为:Circle, Diagonal, Ellipse, Maximum, Minimum。Circle 和 Maximum 会绘制圆形径向渐变,即使对矩形图像也是如此,其半径等于图像半宽和半高中较大的一个。Circle 和 Maximum 都等价于默认径向渐变。Minimum 会绘制圆形径向渐变,即使对矩形图像也是如此,其半径等于图像半宽和半高中较小的一个。Diagonal 会在矩形图像中绘制圆形径向渐变,其半径等于图像半对角线。Ellipse 会在矩形图像中绘制椭圆径向渐变,其半径分别等于图像宽度的一半和高度的一半。ImageMagick 6.9.2-5 版本支持。
gradient:radii=x,y 指定渐变的 x 和 y 半径。如果 x 和 y 半径相等,则径向渐变将具有圆形形状。如果它们不同,它将是一个椭圆。默认值为图像的半宽和半高中的较大者。 ImageMagick 6.9.2-5 版本支持。
gradient:vector=x1,y1,x2,y2 指定从向量 1 (x1,y1) 到向量 2 (x2,y2) 的线性渐变方向。 Color1(起始颜色)放置在向量位置 x1,y1 处,color2(结束颜色)放置在向量位置 x2,y2 处。 ImageMagick 6.9.2-5 版本支持。

径向渐变

IM 从v6.4.4开始,你也可以通过类似的方式生成径向渐变图像。 |

  magick -size 100x100 radial-gradient:  rgradient.jpg

[IM 输出]
请注意,渐变以生成图像的中心为中心,其直径设置为图像的 X 或 Y 尺寸中的较大者。因此,如果你的图像尺寸不是方形的,你将得到“裁剪的”径向渐变。 |

  magick -size 100x60 radial-gradient:  rgradient_clip.jpg

[IM 输出]
这让你可以轻松生成从中心延伸到角落的方形径向渐变:只需生成边长扩大 1.42 倍(2 的平方根)的径向渐变,然后再裁剪即可。 |

  magick -size 100x142 radial-gradient: \
          -gravity center -crop 100x100+0+0 rgradient_crop.jpg

[IM 输出]
渐变本身的颜色遵循与更旧的线性“[gradient:](#gradient)”图像生成器相同的约定

  magick -size 100x100  radial-gradient:blue              rgradient_range1.jpg
  magick -size 100x100  radial-gradient:yellow            rgradient_range2.jpg
  magick -size 100x100  radial-gradient:green-yellow      rgradient_range3.jpg
  magick -size 100x100  radial-gradient:red-blue          rgradient_range4.jpg
  magick -size 100x100  radial-gradient:tomato-steelblue  rgradient_range5.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

具有透明度的渐变

IM 从 v6.2.9-8 开始,“gradient:”(以及后来的“radial-gradient:”)图像创建运算符支持使用透明和半透明颜色。 |

  magick -size 100x100 gradient:none-firebrick gradient_transparent.png

[IM 输出]
| _ImageMagick 在 6.5.4-7 之前,包含完全透明度的渐变(如上一个示例)通常会产生黑色光晕。

发生的情况是,生成的渐变是从指定颜色到特殊颜色“none”,即透明黑色。结果,颜色在变得完全透明之前逐渐变为半透明黑色。

此问题的解决方案是生成透明度渐变并使用所需的颜色对其进行着色。 _
---|---
|

  magick -size 100x100 gradient:none-black \
          -fill firebrick -colorize 100% gradient_trans_colorize.png

[IM 输出]

通过直方图调整生成渐变

你可以通过对线性渐变应用某种形式的直方图调整来创建非线性渐变。例如,你可以使用 S形对比 函数来创建更自然的渐变。 |

  magick -size 100x100 gradient: -sigmoidal-contrast 6,50% \
            gradient_sigmoidal.jpg

[IM 输出]
这种类型的渐变特别适合生成 重叠的照片,因为它消除了重叠区域开始处的急剧渐变变化。

通过评估/函数进行渐变

你还可以使用求值运算符和相关的函数运算符修改简单的线性渐变。 |

  magick -size 100x100 gradient: -evaluate cos 0.5 -negate \
            gradient_cosine.jpg

[IM 输出]
或者更进一步,在线性渐变的中间创建一个平滑的抛物线峰。 |

  magick -size 100x100 gradient: -function Polynomial -4,4,0 \
            gradient_peak.jpg

[IM 输出]
或者条纹或波浪图案... |

  magick -size 100x100 gradient: -function sinusoid 4,-90  \
            gradient_bands.jpg

[IM 输出]
这两个密切相关的运算符都可以基于正弦、多项式、对数和幂数学函数修改图像和渐变。有关更多示例,请参阅计算数学函数函数、多参数计算

渐变失真

旋转渐变

稀疏颜色 的“[Barycentric](#barycentric)”方法(见下文)提供了一种在任何角度生成渐变的便捷方法,但如果你的 IM 版本早于 6.4.3-0,则可能需要另一种方法来生成对角或旋转渐变。例如,你可以通过增加渐变图像的大小(乘以 2 的平方根或 1.42)、将其旋转 45 度并将其裁剪为最终大小来创建对角渐变。 |

  magick -size 142x142 gradient: -rotate -45 \
          -gravity center -crop 100x100+0+0 +repage \
          gradient_diagonal.jpg

[IM 输出]
IM 从 v6.3.5 开始,你可以使用 SRT 扭曲 更快、更轻松地生成旋转渐变。例如,这是在 100x100 像素图像内旋转 60 度的 100 像素渐变。 |

  magick -size 100x100 gradient: -distort SRT 60 gradient_srt.jpg

[IM 输出]
这里使用默认的 虚拟像素,边缘 设置以确保整个图像被请求的渐变覆盖。你还可以使用专家 扭曲视口 设置,将渐变映射到更大的图像上,例如用于 重叠的照片.

渐变扭曲

但同样的扭曲技术可以做的不仅仅是简单的旋转。 你还可以扭转渐变... |

  magick -size 100x100 gradient: -swirl 180 gradient_swirl.jpg

[IM 输出]
你可以将渐变重新映射为梯形。 |

  magick -size 100x100 gradient: -rotate -90 \
          -distort Perspective '0,0 40,0  99,0 59,0  0,99 -10,99 99,99 109,99' \
          gradient_trapezoid.jpg

[IM 输出]
或者,你可以使用一般扭曲运算符 将渐变包裹在圆弧或圆周围... |

  magick -size 100x100 gradient: -distort Arc '180 0 50 0' \
          gradient_arc.jpg

[IM 输出]
|

  magick -size 100x100 gradient: -distort Arc '360 0 50 0' \
          gradient_circle.jpg

[IM 输出]
然而,新的“[radial-gradient:](#radial-gradient)”可能是生成这些渐变的更简单的方法。极坐标渐变是一个非常有用但难以生成的渐变。该渐变的确切形状取决于它是以偶数大小的图像还是奇数大小的图像为中心。例如,你可以使用 Arc 扭曲 生成具有偶数像素尺寸(本例中为 76 像素)的图像。 |

  magick -size 1x1000 gradient: -rotate 90 \
          -distort Arc '360 -90 50 0' +repage \
          -gravity center -crop 76x76+0+0 +repage  gradient_angle_even.png

[IM 输出]
上面的 '-90' 设置了“不连续点”的角度,也就是“零”和“最大”环绕到同一值的位置。值 '50' 应大于最终裁剪图像尺寸的一半。请注意,我用一个长得多的渐变来生成较小图像。这会提高结果的整体正确性,尤其是在图像变大时。密切相关的 Polar Distort 也可以生成这种渐变;由于它能控制畸变“中心”的精确位置,你可以确保正确生成奇数像素尺寸的极坐标渐变图像。本例中是一张 75 像素图像(半径 = '36.5')。 |

  magick -size 1x1000 gradient: -rotate 90 \
          +distort Polar '36.5,0,.5,.5' +repage \
          -transverse  gradient_angle_odd.png

[IM 输出]
最后两张图像除了大小之外看起来非常相似,但最中心像素的处理略有不同。仔细看会发现,最后一个示例有一个完美的灰色中心像素,而前一个示例没有单个中心像素,而是有四个。图像最终尺寸由值“36.5”决定,也就是所需“75”像素的一半。“.5”偏移是正确处理极坐标中心的关键。请注意,默认情况下,畸变会把不连续点放在图像顶部,因此 横向扭曲 会校正不连续点的角度和位置,使其与 Arc 扭曲 产生的结果一致。下面是一个稍有不同的变体,生成角度渐变,但带有透明圆形遮罩。 |

  magick -size 50x1000 gradient: -rotate 90 -alpha set \
          -virtual-pixel Transparent +distort Polar 49 +repage \
          -transverse  gradient_angle_masked.png

[IM 输出]
值“49”是半径减 1。这是因为默认情况下,失真会在生成的图像周围添加 1 像素的抗锯齿缓冲区。结果,最终图像将为 100x100 像素。
圆形和渐变可以扭曲以产生一些有趣的非线性渐变。例如,使用 波形畸变 可以生成大致三角形的渐变。 |

  magick -size 100x100 radial-gradient: \
          -background black -wave -28x200 -crop 100x100+0+0 +repage \
          gradient_triangle.jpg

[IM 输出]
或者通过沿圆形形状的顶部边缘应用极坐标扭曲而产生非常奇怪的鸟状形状。 |

  magick -size 100x100 radial-gradient: \
          +distort Polar '49' +repage \
          gradient_bird.jpg

[IM 输出]

通过合成生成渐变

你还可以使用各种合成方法组合并修改渐变。例如,可以使用 Modulus_Add 合成方法生成百叶窗状的渐变。 |

  magick -size 100x100 gradient: \( +clone +clone \) \
          -background gray50 -compose ModulusAdd -flatten \
          gradient_venetian.jpg

[IM 输出]
你甚至可以对角地这样做。 |

  magick -size 100x100 gradient: \( gradient: -rotate -90 \) \
          \( -clone 0--1 -clone 0--1 \) \
          -background gray50 -compose ModulusAdd -flatten \
          gradient_vent_diag.jpg

[IM 输出]
或者通过使用以下任一方法混合两种纯色渐变 通道复制, 或 数学混合 合成方法,你可以生成彩色的二维颜色图渐变。 |

  magick -size 100x100 gradient:yellow-blue \
          \( gradient:black-lime -rotate -90 \) \
          -compose CopyGreen -composite  gradient_colormap.jpg

[IM 输出]

其他色彩空间中的渐变

虽然“gradient:”生成器目前无法直接在其他色彩空间中生成渐变(只会创建非线性 sRGB 渐变图像),但你可以把渐变转移到不同的色彩空间中,以生成有趣的效果。例如...

  magick -size 30x600 xc:red -colorspace HSB \
          gradient: -compose CopyRed -composite \
          -colorspace RGB -rotate 90  gradient_rainbow.jpg

[IM 输出]

它首先将高度饱和的颜色(“red”)转换为 HSL 色彩空间。你可以使用任何高饱和度的颜色。这会将图像的饱和度和亮度通道正确设置为适当的值。然后,我们生成一个渐变并将其复制到此 HSL 色彩空间图像的“色调”(相当于“红色”)通道。现在,当你将 HSL 图像转换回 RGB 时,你将获得完全饱和颜色的彩虹渐变。另一种方法是为这些色彩空间之一生成具有正确值的渐变,然后更改图像的色彩空间(使用“[-set](https://imagemagick.org/command-line-options/#set)”)。这会更改色彩空间,但不会更改图像中创建的颜色值。然后转换回RGB,你会得到具有相同值的彩虹

  magick -size 30x600 gradient:'#FFF-#0FF' -rotate 90 \
          -set colorspace HSB -colorspace RGB \
          gradient_rainbow_2.jpg

[IM 输出]

结果其实和前一种方法完全相同,只是更直接一点:先为目标色彩空间生成正确的值,再设置这些值所属的色彩空间。这里我们取带遮罩的角度渐变(见上文),并把它重新映射到 HSB 色彩空间中,生成圆形色相环。红色(色相 = 0)被旋转到右侧,也就是传统位置(极坐标角度 0)。 |

  magick -size 100x300 gradient:'#FFF-#0FF' -rotate 90 \
          -alpha set -virtual-pixel Transparent +distort Polar 49 +repage \
          -rotate 90 -set colorspace HSB -colorspace RGB \
          gradient_hue_polar.png

[IM 输出]
与上述类似的示例是色轮。这是通过组合通道图像 使用色调和亮度渐变生成的。

通过调整尺寸进行渐变

Glenn Randers-Pehrson 向我展示的一个技巧是创建一个非常小的图像,2 像素宽,并使用“[-resize](https://imagemagick.org/command-line-options/#resize)”将其缩放到所需的图像大小。 调整尺寸运算符 尝试平滑缩放后的图像,使其在较大比例下看起来更好。这种平滑用于生成非线性渐变。 例如,这里我们使用“便携式位图”(PBM 格式)图像生成小图像并将其传递给 IM 进行放大。 |

  echo "P1 1 2   0  1 " | \
  magick - -resize 100x100\!   gradient_resize.jpg

[IM 输出]
| 某些 shell(例如 'csh' 及其变体)不能很好地处理上面调整尺寸几何参数中的“!”字符,即使用引号括起来也是如此。因此可能需要反斜杠“\”字符。请小心。
---|---
生成的渐变不是线性的,但指定颜色具有平滑的开始和结束,使它们比常规渐变更加明显。渐变遵循的实际函数取决于(并将接近)调整尺寸时使用的精确重采样滤波器。 生成第一个 2 像素图像的一个简单方法实际上是使用渐变本身!这允许你直接指定颜色。当然,结果仅限于垂直渐变,除非你也旋转它们。 |

  magick -size 1x2  gradient:khaki-tomato \
          -resize 100x100\!   gradient_resize2.jpg

[IM 输出]
当然,这种技术并不局限于一维。这里我们将使用 4 像素“便携式灰度图”(PGM 图像格式)来生成 2D 渐变。 |

  echo "P2 2 2 2   2 1 1 0 " | \
  magick - -resize 100x100\!   gradient_resize3.jpg

[IM 输出]
正如你所看到的,这个对角渐变的线性度不如上面的旋转渐变。 | 网络便携式位图 图像格式对于从脚本生成图像非常通用。作为生成或操作图像数据的一种方式,这种格式非常值得了解。
---|---
如果仔细观察,还可以看到渐变从放大像素的中心开始,并没有从边缘到边缘完全覆盖图像。使用三角形调整尺寸滤镜 时,这一点变得更加清晰。 |

  magick \( xc:red xc:blue +append \) \
          \( xc:yellow xc:cyan +append \) -append \
          -filter triangle -resize 100x100\!   gradient_resize4.jpg

[IM 输出]
调整尺寸运算符 根据“[Resampling Filter](filter.html#filter)”设置平滑这些像素之间的颜色。通过调整滤镜,可以使调整尺寸创建的渐变具有更边缘到边缘的效果。 |

  magick -size 1x2  gradient: \
          -filter Cubic  -resize 100x100\!    gradient_resize5.jpg

[IM 输出]
接下来是使用“调整尺寸”方法创建的粗略“彩虹渐变”。

  magick xc:black xc:red xc:yellow xc:green1 xc:cyan xc:blue xc:black \
          +append -filter Cubic -resize 600x30\! gradient_rs_rainbow.jpg

[IM 输出]

此方法允许你使用颜色的任意组合和顺序来生成渐变。这使得它非常适合生成颜色查找表

带插值查找的渐变

有关“[-interpolate](https://imagemagick.org/command-line-options/#interpolate)”设置的详细信息,请参见插值设置。另一种生成渐变的方法是使用特殊的插值设置。此设置用于确定在像素查找不是整数且不完全匹配特定像素时返回的像素颜色。插值根据查找点周围的像素确定颜色。例如,默认设置“bilinear”线性确定位于两个像素之间的查找的颜色

  magick -size 600x30 xc:   \( +size xc:gold xc:firebrick +append \)  \
          -fx 'v.p{i/(w-1),0}'    gradient_interpolated.jpg

[IM 输出]

这里,查找用的 X 位置 'i/(w-1)' 会在第二个两像素图像上从 '0.0' 变化到 '1.0'。这个浮点数会产生完美的线性渐变,很像 "[gradient:](#gradient)" 所做的那样。上面的做法实际上几乎等同于(差异见 完美渐变)使用 Clut 重新着色图像" 通过对两色图像进行插值查找来给渐变图像重新着色。

  magick -size 30x600 gradient: -rotate 90 \
          \( +size xc:gold xc:firebrick +append \) -clut \
          gradient_clut_recolored.jpg

[IM 输出]

使用这种方法,还可以生成多色渐变

  magick -size 30x600 gradient: -rotate 90  -interpolate Bicubic \
          \( +size xc:black xc:tomato xc:wheat +append \) -clut \
          gradient_clut.jpg

[IM 输出]

但限制是颜色只能以相等的间距定义。你不能简单地移动中间颜色的位置,除非将输入渐变粗略地修改为某种非线性形式,从而移动该中心。对于超过三种颜色则情况变得更糟。以上也是使用 双色调 方法对灰度图像进行着色的好技术,可保证精确定义中间调颜色(这与使用 色调运算符 不同)。
具有插值查找的渐变也可以扩展到二维,像纯一维渐变一样轻松地生成方形线性渐变(Bilinear 插值)。 |

  magick \( xc:red xc:blue +append \) \
          \( xc:yellow xc:cyan +append \) -append \
          -size 100x100 xc: +swap  -fx 'v.p{i/(w-1),j/(h-1)}' \
          gradient_bilinear.jpg

[IM 输出]
这里是同一个示例,但使用 Catrom 插值,并用 Distort 运算符生成,而不是使用非常慢的 FX 运算符。 |

  magick \( xc:red xc:blue +append \) \
          \( xc:yellow xc:cyan +append \) -append \
          -filter point -interpolate catrom \
          -define distort:viewport=100x100 \
          -distort Affine '.5,.5 .5,.5   1.5,1.5 99.5,99.5' \
          gradient_catrom.jpg

[IM 输出]
理解上述内容的关键点是我们根据小图像的像素中心来放大小图像。参见 图像坐标与像素坐标 了解详情。请注意,大多数插值方法具有等效的 插值调整尺寸过滤器。但是视口和像素坐标的使用消除了前面显示的边缘效果 调整渐变大小 由非常小的图像的极端放大引起的。
但是,网格插值 设置不可用作调整尺寸滤镜。这是一种特殊类型的二维插值,它将像素内的区域划分为两个平面线性三角形,这两个三角形沿着色差最小的角之间的对角线铰接。因此,如果你使两种颜色相同并使用“-interpolate mesh”,你可以产生非常不同的 2D 渐变。 |

  magick \( xc:red xc:gold +append \) \
          \( xc:gold xc:green +append \) -append \
          -filter point -interpolate mesh \
          -define distort:viewport=100x100 \
          -distort Affine '.5,.5 .5,.5   1.5,1.5 99.5,99.5' \
          gradient_mesh.jpg

[IM 输出]
由于对角相对的两个黄色角是相同的,因此使用黄色对角线将它们连接起来。其他颜色线性映射到这些三角形。如果对角线上的两种颜色不相同,则可能会得到不同的对角线分割。

创建你自己的渐变

FX DIY 运算符 允许你根据当前像素位置定义自己的渐变和其他图像生成。该运算符需要使用图像,因此它可以生成渐变和其他图像来匹配该图像。这意味着你不需要知道图像的大小来生成渐变!例如,你可以轻松地为你正在处理的图像生成正确大小的线性渐变。 |

  magick rose: -channel G -fx 'i/w' -separate   gradient_fx_linear.gif

[IM 输出]
| 生成灰度渐变时,只需要求 -fx 运算符仅生成单个颜色通道(例如上例中的“G”(绿色)通道),就可以使其速度提高三倍。然后可以将该通道分离以形成所需的灰度图像。这可以提供巨大的加速,特别是在使用非常复杂的“[-fx](https://imagemagick.org/command-line-options/#fx)”表达式时。
---|---
你甚至可以生成漂亮的非线性渐变。 |

  magick rose: -channel G -fx '(i/w)^4' -separate   gradient_fx_x4.gif

[IM 输出]
|

  magick rose: -channel G -fx 'cos(pi*(i/w-.5))' \
           -separate   gradient_fx_cos.gif

[IM 输出]
二维圆形线性径向渐变(圆锥体)怎么样? |

  magick -size 100x100 xc: -channel G \
          -fx 'rr=hypot(i/w-.5, j/h-.5); 1-rr*1.42' \
          -separate gradient_fx_radial.gif

[IM 输出]
| "[-fx](https://imagemagick.org/command-line-options/#fx)" 函数“rr=hypot(xx,yy)”是在 IM v6.3.6 中加入的,用于加速常用表达式“rr=sqrt(xx*xx+yy*yy)”。此外,在创建径向渐变时,你不再需要额外的赋值表达式,例如“xx=i/w-.5”。
---|---
上面的值 '1.42'(或 sqrt(2))控制渐变相对于图像尺寸的整体大小。这样,渐变的半径(黑色离中心有多远)就是到角点的对角距离。你甚至可以从表达式中去掉 'sqrt()'(内置在 'hypot()' 函数中),从而得到更有趣的球面渐变,这对于 3D 阴影效果 很有用。 |

  magick -size 100x100 xc: -channel G \
          -fx 'xx=i/w-.5; yy=j/h-.5; rr=xx*xx+yy*yy; 1-rr*4' \
          -separate gradient_fx_spherical.gif

[IM 输出]
请注意,我们如何使用一些赋值表达式来简化到图像中心距离的计算,然后把它转换为渐变。该功能已在 IM v6.3.0 中加入。 使用高次函数会产生让图像在矩形边缘附近淡出的效果。调整幂值“4”即可控制淡出量。 |

  magick -size 100x100 xc: -channel G \
          -fx '(1-(2*i/w-1)^4)*(1-(2*j/h-1)^4)' \
          -separate  gradient_fx_quad2.gif

[IM 输出]
接下来是使用简单数学生成的角度渐变。 |

  magick -size 100x100 xc:  -channel G \
          -fx '.5 - atan2(j-h/2,w/2-i)/pi/2' \
          -separate  gradient_fx_angular.gif

[IM 输出]
请注意,'atan2(y,x)' 函数返回从 -PI 到 +PI 的弧度角度(请参阅其联机帮助页),因此需要对其输出进行缩放和转换以正确适应 0.0 到 1.0 的颜色范围。这就是为什么上面看起来比实际复杂得多。最后一个例子可以通过以下方式更快地生成 扭曲渐变.

更复杂的 DIY 渐变

_旁注:此部分是在添加稀疏颜色点之前创建的,对其创建有直接影响。 _当然,FX函数可以生成颜色渐变。例如,这是一个基于距离比的渐变,使用极其复杂的公式FX。 |

  magick -size 100x100 xc: +size xc:red xc:yellow -colorspace RGB \
          -fx 'ar=hypot( i/w-.8, j/h-.3 )*4;
               br=hypot( i/w-.3, j/h-.7 )*4;
               u[1]*br/(ar+br) + u[2]*ar/(ar+br)' \
          -colorspace RGB gradient_dist_ratio.gif

[IM 输出]
| 为了避免在混合如此强烈的原色时出现“sRGB 变暗”,图像处理是在线性色彩空间 (RGB) 中完成的。有关详细信息,请参见处理真实图像
---|---
从 2 点变为 3 点,每个“控制点”提供的颜色数量的比率变得更加复杂,使用一种称为反距离加权 (IDW) 插值的技术。该数学的详细信息可以在 Wikipedia, IDW 中找到。以下是三点距离反比的示例。 |

  magick -size 100x100 xc: +size xc:red xc:yellow xc:lime -colorspace RGB \
          -fx 'ar=1/max(1, hypot(i-50,j-10)  );
               br=1/max(1, hypot(i-10,j-70)  );
               cr=1/max(1, hypot(i-90,j-90)  );
               ( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
          -colorspace sRGB gradient_inverse.gif

[IM 输出]
这里是一个使用反距离平方的例子,它在 IDW 插值中更常用。这也称为 Shepard 插值。 |

  magick -size 100x100 xc: +size xc:red xc:yellow xc:lime -colorspace RGB \
          -fx 'ar=1/max(1,  (i-50)*(i-50)+(j-10)*(j-10)  );
               br=1/max(1,  (i-10)*(i-10)+(j-70)*(j-70)  );
               cr=1/max(1,  (i-90)*(i-90)+(j-90)*(j-90)  );
               ( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
          -colorspace sRGB gradient_shepards.gif

[IM 输出]
请注意,我们没有使用上面的“hypot()”函数,因为我们不需要生成距离的平方根。以上目前是使用稀疏颜色的“[Inverse](#inverse)”和“[Shepard's](#shepards)”方法来实现的。所以现在可以更轻松地完成上述操作

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color  Inverse '50,10 red  10,70 yellow  90,90 lime' \
          -colorspace sRGB  gradient_inverse_alt.gif
  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color  Shepards '50,10 red  10,70 yellow  90,90 lime' \
          -colorspace sRGB  gradient_shepards_alt.gif

[IM 输出] [IM 输出]

使用“反距离”或“谢泼德方法”(反平方距离)的问题是每个“控制点”对整个图像都有全局影响。结果是点之间的一种潜在“平均颜色”,尤其是远离所有控制点的情况。这会导致颜色“斑点”,而不是平滑的颜色渐变。

DIY 渐变和色调

--(色调很难处理)

_旁注:可以说,这是一次失败的尝试,无法产生有趣的彩虹效果。这是一次失败,但我从这次失败中学到了很多东西。我就在这里介绍一下。 _ 上面的效果很好,但我想尝试让它变得更好。我认为,与其产生与平均颜色混合的斑点,不如在点之间产生明亮的彩虹渐变。因此,为了生成色调渐变,我尝试在 HSB 色彩空间中进行 反距离加权插值。不过,我将黄色切换为蓝色,以便可以在色调周围更均匀地分布颜色,并希望提供另一种生成色轮的方法(请参阅上面的其他色彩空间中的渐变)。 |

  magick -size 100x100 xc: +size xc:red xc:blue xc:lime -colorspace HSB \
          -fx 'ar=1/max(1,  (i-50)*(i-50)+(j-10)*(j-10)  );
               br=1/max(1,  (i-10)*(i-10)+(j-70)*(j-70)  );
               cr=1/max(1,  (i-90)*(i-90)+(j-90)*(j-90)  );
               ( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
          -colorspace sRGB   gradient_shepards_HSB.gif

[IM 输出]
如你所见,所有颜色都漂亮而明亮,因为我们只生成色相渐变。但它看起来也很奇怪。这是由“色相”颜色通道的“循环”性质引起的。因此,蓝色和红色之间的区域走的是经过绿色色相的长路径,而不是经过紫色色相的短取模路径。经过大量研究,我终于弄清楚,要正确完成上述操作,需要使用圆形平均值来进行距离加权平均所需的取模数学。这涉及把作为极角的色相转换成 X 和 Y 正交坐标,从而可以使用线性数学和正确的线性权重值,然后再把结果转换回角度色相。 |

  magick -size 100x100 xc: +size xc:red xc:blue xc:lime \
          -colorspace HSB -channel R \
          -fx 'aa=u[1]*2*pi; ba=u[2]*2*pi; ca=u[3]*2*pi;
               ar=1/max(1, hypot(i-50,j-10) );
               br=1/max(1, hypot(i-10,j-70) );
               cr=1/max(1, hypot(i-90,j-90) );
               nr=ar+br+cr;
               mod(atan2( ( sin(aa)*ar + sin(ba)*br + sin(ca)*cr )/nr,
                         ( cos(aa)*ar + cos(ba)*br + cos(ca)*cr )/nr
                       )/(2*pi)+1, 1)' \
          -separate -background white -combine +channel \
          -set colorspace HSB -colorspace sRGB  gradient_circular_mean_hue.gif

[IM 输出]
注意:以上操作仅在 Hue 通道上进行。在真实图像中,你还需要对饱和度和亮度通道进行操作(像往常一样)。正如你所看到的,我们现在在红色和蓝色之间有了正确的渐变。然而,如果此方法仅应用于具有大角距的原色,则它往往会在中心产生非常突然的渐变变化。换句话说,虽然结果是正确的,但对于色调效果的非常大的变化,角度色调变化不是线性的。它适用于平均许多相似的色调,但不适用于这些相距较远的原色。我还尝试改用更强的“逆加权”,而不是更常见的“反平方”或“Shepard”方法(见上文),尽管有一些改进,但由于非线性效应,色调变化仍然在中心被压缩。由于输入颜色是常量,因此首先将它们转换为色调 x 和色调 y 坐标,对这些通道执行 Shepard 加权,然后再次将它们转换回来实际上会更快。即,将颜色从 HSB 色彩空间转换到 Hx,Hy,S,B 色彩空间并应用此方法。如果执行此操作,中心点以及点之间的均匀渐变将变为白色(HSB 色彩空间中的中心点)。如果你在 HSL 色彩空间中执行此操作,该区域将被着色为中间色调灰色。
这种从极坐标到 X-Y 坐标的转换在某些方面类似于在非极 RGB 空间中执行计算。 RGB 空间呈现出相同灰色的阴影效果(参见前面的示例)。因此,如果通过使用 Circular Mean,你实际上只是将 HSB 色彩空间转换为高度扭曲的变体 RGB,那么为什么不在线性 RGB 色彩空间中进行这项工作并增加颜色的饱和度以生成色调呢?

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color  Inverse '50,10 red  10,70 blue  90,90 lime' \
           -colorspace sRGB gradient_inverse_RGB.png
  magick gradient_inverse_RGB.png -colorspace HSB \
          -channel GB -evaluate set 100% +channel \
          -colorspace sRGB gradient_inverse_RGB_Hue.gif

[IM 输出] [IM 输出]

| 为了避免在混合如此强烈的原色时出现“sRGB 变暗”,图像处理是在线性色彩空间 (RGB) 中完成的。有关详细信息,请参见处理真实图像
---|---
正如你所看到的,即使我们删除了所有复杂的“余数数学”,我们也得到了与以前几乎完全相同的结果。然而,我们仍然没有更接近于在颜色起点之间创建更线性的色调分布。所有这一切的教训是色调很难处理。不仅因为“红色不连续性”,还因为颜色相距很远时会出现非线性效应。事实证明,结果与直接在线性 RGB 空间中工作并使颜色饱和的结果相同。从本质上讲,HSB 和 HSL 色彩空间虽然有趣,但并不是线性、现实或实用的色彩空间。这可能也是为什么实际上直接使用色调的操作如此之少的原因。

生成完美的渐变(数学上)

生成完美的数学渐变,例如 傅里叶变换 (这是循环的), 图像映射,甚至 渐变数学;需要与我们迄今为止看到的渐变不同的特殊渐变。 我这是什么意思?这是一个小的 1x5 像素”gradient:“图像,我有 缩放 这样你就可以看到各个像素的颜色。 |

  magick -size 1x5 gradient:  -scale 2000% gradient.png

[IM 输出]
该图像创建了从沿顶行的精确“白色”颜色到沿底行的精确“黑色”颜色的渐变。这是一个“理想化”的渐变,它实际上包含用户指定的实际颜色,因此它通常正是用户想要的。然而,尽管这是用户所期望的,但它并不是数学上正确的渐变。正如图像坐标与像素坐标中所讨论的,像素实际上具有面积。因此,图像顶部的白色像素代表该像素的中心,黑色代表底部像素的中心。也就是说,不是在图像的边缘,而是距离边缘 1/2 像素处。从数学上讲,图像从边缘开始。因此,要生成完整的数学渐变,必须以像素坐标指定图像边缘颜色的位置。即在图像坐标中,位置偏移1/2像素,图像大小是图像中确切的像素数(距离)(而不是比图像大小小1个像素的位置)。生成数学上完美渐变的一种方法是使用 Barycentric 稀疏颜色(下一节将详细介绍)生成完美的边到边渐变… |

  magick -size 1x5 xc: \
          -sparse-color Barycentric '0,-0.5 white  0,%[fx:h-.5] black' \
          -scale 2000%  gradient_math.png

[IM 输出]
请注意,使用的坐标从 -0.5 到图像高度减 0.5,也就是图像实际边缘的像素坐标。仔细观察结果会发现,顶部和底部像素的颜色不是白色或黑色;像素取得的是像素中心处的渐变颜色。这个渐变在数学上是正确的,并且在特殊的“平铺”或“循环”场景中使用时会正确地“平铺”。前面的渐变图像并没有正确“平铺”。纯白像素紧挨着纯黑像素,而在纯白和纯黑通常被视为等价值的数学循环中,这会产生一个单像素间隙或“不连续点”。更简单的方法是生成一个长 1 像素的“[gradient:](#gradient)”图像,并从两端切掉 1 个像素(依据当前“[-gravity](https://imagemagick.org/command-line-options/#gravity)”设置)。 例如,这里我切掉顶部的白色像素,因为通常希望最终结果中有黑色像素(或零值)。 |

  magick -size 1x6 gradient: -chop 0x1 -scale 2000%  gradient_chopped.png

[IM 输出]
然后可以根据需要对所得渐变图像进行旋转,以生成后续图像处理所需的图像。然而,尽管此渐变正确“循环”,但颜色的实际位置并不完全正确。然而,在许多情况下这已经足够了。如果你想要“完美的渐变”,我们建议使用稀疏颜色渐变。 总而言之... 只要稍微考虑一下你想要从渐变中得到什么,就可以对最终结果的准确性产生很大的影响。但如果这并不重要,请随意使用最简单的方法来完成手头的任务。


稀疏颜色点

"[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) " 运算符是在 IM v6.4.3-0 中加入的;它会取一幅图像,并在每个给定的浮点 'x,y' 坐标处设置指定颜色。也就是如下形式...

-sparse-color {method}  'x,y color   x,y color   x,y color ...'

其余像素(根据“[-channel](https://imagemagick.org/command-line-options/#channel)”设置)随后会根据它们与这些孤立颜色点的关系进行映射,从而平滑这些点之间的颜色。方法定义了这种关系。当然,可以用很多方法来定义中间颜色应该是什么,选择哪一种实际上取决于你想实现什么。它也可以归类为二维插值的完全自由形式版本(见插值,维基百科)。图像放大,或调整尺寸,实际上是它的一个专门子集,只不过你从一个完整、固定的像素网格开始进行放大。遗憾的是,为网格点设计的 调整尺寸滤镜插值方法,很少能直接用于这种自由形式、稀疏分布的颜色点集合。也就是说,涉及不完整网格的调整尺寸是行不通的。这也与“地理信息系统(GIS)”方法有关,其中使用稀疏分布的高度点(很少处于严格网格中)来测量地形,而地形的其余部分则由这些孤立点确定。在类似情况下,气象学常常只有气压和温度的孤立点,然后需要对它们插值。通常,插值之后,地图会进一步处理,生成显示相同值(高度、气压、温度)的“等值线”,形成几乎每个人都熟悉的各种天气图。在这种情况下,可以把生成图像看作输入数据的一张简单灰度“高度图”,甚至也可能同时表示三个变量,每个变量使用单独的图像“通道”。

Barycentric(三角形渐变)

Barycentric”方法将 3 个点(并且只有 3 个点)映射到线性三角形的颜色。这个三角形外面的颜色继续像以前一样。输入点用小圆圈标记,因此所有可见颜色都是稀疏颜色运算符生成的插值。 |

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color  Barycentric '30,10 red   10,80 blue   90,90 lime' \
          -colorspace sRGB  -fill white -stroke black \
          -draw 'circle 30,10 30,12  circle 10,80 10,82  circle 90,90 90,92' \
          sparse_barycentric.png

[IM 输出]
| 为了避免在混合如此强烈的原色时出现“sRGB 变暗”,图像处理是在线性色彩空间 (RGB) 中完成的。有关详细信息,请参见处理真实图像
---|---
如果给出 4 个或更多点,则会对所有给定点进行“最佳拟合”,这可能导致实际点无法得到为这些点指定的确切颜色。但请注意,渐变并不会简单地“停止”,而是会继续在这些点之外变化。传统上,重心渐变会被限制在包围生成点的三角形内部。例如... |

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color Barycentric '30,10 red   10,80 blue   90,90 lime' \
          -colorspace sRGB  -fill white -stroke black \
          \( -size 100x100 xc:black -draw 'polygon 30,10  10,80  90,90' \) \
          -alpha off -compose CopyOpacity -composite \
          -draw 'circle 30,10 30,12  circle 10,80 10,82  circle 90,90 90,92' \
          sparse_bary_triangle.png

[IM 输出]
|

  magick -size 100x100 xc:none -draw "polygon 30,10  10,80  90,90" \
          -colorspace RGB -channel rgb \
          -sparse-color Barycentric '30,10 red   10,80 blue   90,90 lime' \
          -colorspace sRGB  sparse_bary_triangle_2.png

[IM 输出]
| 由于绘图的性质,在形状周围绘制一条额外的线,所以上面使用的三角形遮罩太大了 1/2 像素。有关详细信息,请参见绘制填充边界。生成渐变三角形网格时这可能是一个问题。
---|---
barycentric”方法实际上将线性仿射方程分别映射到三个颜色通道中的每一个。因此,如果我们在上面的 3 点示例中分离每个颜色通道,我们会在每个颜色通道中得到 3 个简单的线性渐变

  magick sparse_barycentric.png -separate sparse_bary_%d.gif

[IM 输出] [IM 输出] [IM 输出] [IM 输出]

只是因为我们使用了原色,所以上面的渐变都平行于三角形的一侧映射。通常情况并非如此。然而,图像的每个单独通道始终会产生简单的线性渐变,而 3D 色彩空间会产生平坦的值平面。

Barycentric 和两种颜色渐变

三角形重心渐变的这种平行效果实际上非常有用。当你将两个点设置为相同颜色时,这两个点定义它们与其他颜色的点之间的渐变“角度”。例如,通过使两个点“red”,渐变将平行于两个“red”点...|

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color  Barycentric '30,10 red   10,80 red   90,90 lime' \
          -colorspace sRGB  -fill white -stroke black \
          -draw 'circle 30,10 30,12  circle 10,80 10,82  circle 90,90 90,92' \
          sparse_bary_gradient.png

[IM 输出]
下面是相同的示例,但移动角度控制点之一以显示它如何设置渐变角度。 |

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color  Barycentric '50,70 red   10,80 red   90,90 lime' \
          -colorspace sRGB  -fill white -stroke black \
          -draw 'circle 50,70 50,72  circle 10,80 10,82  circle 90,90 90,92' \
          sparse_bary_gradient_2.png

[IM 输出]

对角渐变

这提供了一种仅使用两种颜色生成任意线性对角渐变的简单方法。例如,这是一种为任意大小的输入图像创建从一个角到另一个角的对角渐变的特别好方法

  magick -size 600x60 xc: -colorspace RGB \
          -sparse-color barycentric '0,0 skyblue  -%w,%h skyblue  %w,%h black' \
          -colorspace sRGB diagonal_gradient.jpg

[IM 输出]

并适合另外两个角

  magick -size 600x60 xc: -colorspace RGB \
          -sparse-color barycentric '0,%h black  -%w,0 black  %w,0 skyblue' \
          -colorspace sRGB diagonal_gradient_2.jpg

[IM 输出]

即使在像上面这样的长图像中,这些“对角渐变”也会产生自然的渐变。仔细观察三个颜色点的位置,尤其是定义两个角之间渐变角度的两个相同颜色的点。请注意,在这两种情况下,这些点之一甚至都不位于图像本身内部!另请注意,我使用 Percent Escapes,以便渐变自动将其位置调整为所绘制图像的大小。

2 点渐变

如果你仅提供两个颜色点,IM 将自动生成第三个点,以便原始两点之间的角度垂直。结果是一个具有大量控制的简单线性渐变。 |

  magick -size 100x100 xc:  -colorspace RGB \
          -sparse-color  Barycentric '30,10 red  90,90 lime' \
          -colorspace sRGB  -fill white -stroke black \
          -draw 'circle 30,10 30,12  circle 90,90 90,92' \
          sparse_bary_two_point.png

[IM 输出]
不过,当应用到非常“宽”或“高”的图像(高宽高比)的角落时,两点渐变效果并不好。基本上,与上面的 3 点渐变不同,渐变并不是沿对角线对齐的。它确实有角度,但角度不够明显,显得不够有趣。

  magick -size 600x60 xc: -colorspace RGB \
          -sparse-color barycentric '0,0 skyblue  %w,%h black' \
          -colorspace sRGB  sparse_bary_two_point_wide.jpg

[IM 输出]

Bilinear(4 点渐变)

此方法将方程拟合到所有三个颜色通道上的四个点,从而在点之间和点之外产生均匀的颜色渐变。 |

  magick -size 100x100 xc:  -colorspace RGB \
    -sparse-color Bilinear '30,10 red  10,80 blue  70,60 lime  80,20 yellow' \
    -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_bilinear.png

[IM 输出]
取上面的图像并分离各个颜色通道的渐变,就可以看到这种“4 点拟合”。

  magick sparse_bilinear.png -separate sparse_bilin_%d.gif

[IM 输出] [IM 输出] [IM 输出] [IM 输出]

请注意,该方程会产生一条曲线(实际上是二次曲线)。但是,如果这 4 个点形成平行线,生成的渐变就会变为线性。当 4 个点在正交(矩形)网格上对齐时,此方法实际上等同于 Bilinear 插值方法(见下方插值查找渐变)。如果给出的点少于 4 个,上述函数会替换为 3 点“[Barycentric](#barycentric)”方法(见上文)。如果点超过 4 个,它会对所有点进行最佳拟合,因此你指定的点可能不会实际呈现你指定的颜色。不建议这样做。

Voronoi(最近颜色)

Voronoi”方法只是将每个像素映射到你提供的最接近的颜色点。这实质上将图像划分为每个点周围的一系列多边形“单元”。例如... |

  magick -size 100x100 xc:  -colorspace RGB \
    -sparse-color  Voronoi '30,10 red  10,80 blue  70,60 lime  80,20 yellow' \
    -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_voronoi.gif

[IM 输出]
正如你所看到的,没有尝试对每个点周围的彩色“单元”进行抗锯齿。每个像元的边缘实际上恰好落在每个点的最近邻居之间的中间。例如,这可以用于生成以不同方式剪切图像的蒙版。你可以通过将一个点指定为白色并将其余所有点指定为黑色来从图像中提取一个“单元格”。如果你想平滑结果(抗锯齿),你可以使用某种超采样来平滑图像。例如,生成一个 4 倍大的文件,然后使用“[-scale](https://imagemagick.org/command-line-options/#scale)”将其返回到你想要的大小。 |

  magick -size 400x400 xc: -colorspace RGB \
    -sparse-color Voronoi '120,40 red 40,320 blue 270,240 lime 320,80 yellow'
\
    -scale 25%  -colorspace sRGB -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_voronoi_ssampled.png

[IM 输出]
| 为了避免在混合如此强的原色时出现“sRGB 变暗”,所有图像处理均在线性色彩空间 (RGB) 中完成。详细信息请参见处理真实图像
---|---
一种更简单的方法(但不是很漂亮)是简单地稍微模糊图像...... |

  magick -size 100x100 xc: -colorspace RGB \
    -sparse-color Voronoi '30,10 red  10,80 blue  70,60 lime  80,20 yellow' \
    -blur 1x0.7  -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_voronoi_smoothed.png

[IM 输出]
通过极大地模糊生成的图像,你可以在生成的“单元”之间设置非线性渐变。 |

  magick -size 100x100 xc:  -colorspace RGB \
    -sparse-color  Voronoi '30,10 red  10,80 blue  70,60 lime  80,20 yellow' \
    -blur 0x15  -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_voronoi_blur.png

[IM 输出]
[-blur](https://imagemagick.org/command-line-options/#blur)”越大,各个“单元”之间的渐变就越大。但请注意,这可能无法保留小的彩色单元格,也不能保证原始点靠近不同颜色单元格(或另一个点)的边缘时将保持给定的颜色。 Fred Weinhaus 开发的特殊“线性模糊”技术允许你在单元格之间生成固定宽度的线性渐变。 |

  magick -size 100x100 xc: -colorspace RGB \
    -sparse-color  Voronoi '30,10 red  10,80 blue  70,60 lime  80,20 yellow' \
    -blur 10x65535  -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_voronoi_gradient.png

[IM 输出]
未模糊的输出也可以传给各种 边缘检测 技术,以生成各种有界边缘。你可以通过 栅格到矢量转换器 重新映射图像来生成矢量线。不过我发现默认的 'autotrace' 设置可能需要用 "-corner-threshold 120" 调整,这样才能更好地检测角点。

Shepards(彩色斑点)

Shepards”方法使用到每个点距离平方的反比比例,来确定画布上每个位置的颜色。有关数学计算如何完成的示例,请参见上面的更复杂的 DIY 渐变。这有点像每个点都有一盏彩色聚光灯彼此相互作用;随着光线扩散,在无穷远处会趋向所有给定颜色的均匀平均值。 |

  magick -size 100x100 xc: -colorspace RGB \
    -sparse-color  Shepards '30,10 red  10,80 blue  70,60 lime  80,20 yellow'
\
    -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_shepards.png

[IM 输出]
| 为了避免在混合如此强烈的原色时出现“sRGB 变暗”,图像处理是在线性色彩空间 (RGB) 中完成的。有关详细信息,请参见处理真实图像
---|---
通过用相似的颜色包围特定区域,你可以生成该特定颜色的高原。然而,封闭点之间的边界可能会“泄漏”,并且“平台”的中心可能会弯曲(取决于其与其他颜色点的距离)成浅碗形状。此方法还用于生成位移场,例如 Shepards 图像扭曲 中使用的位移场。在这种情况下,映射的不是颜色的R、G、B值,而是X和Y位移向量。

Inverse(尖锐的彩色点)

Inverse”方法与“Shepards”类似,只是它使用给定点的更直接的反距离加权。有关如何完成数学运算的示例,请参阅上面的更复杂的 DIY 渐变。这是 ImageMagick 版本 6.6.9-7 的较晚添加内容。例如...|

  magick -size 100x100 xc: -colorspace RGB \
    -sparse-color  Inverse '30,10 red  10,80 blue  70,60 lime  80,20 yellow' \
    -colorspace sRGB  -fill white -stroke black \
    -draw 'circle 30,10 30,12  circle 10,80 10,82' \
    -draw 'circle 70,60 70,62  circle 80,20 80,22' \
    sparse_inverse.png

[IM 输出]
正如你所看到的,它会产生尖锐的颜色点,并快速融入背景的“平均颜色”。这与 Shepards 方法 形成对比,后者产生圆形斑点并在色点周围具有“平坦”颜色。然而,当产生所有控制点形成一条线的线性渐变时,它的效果更好。也就是说,当你想要沿着图像中的特定线生成一维渐变时。不过,还有一件事值得一提。这些色点下降到大约“平均”水平的速度取决于它们的接近程度。如果将两个点源靠近放置,它们会很快下落;它们相距越远,各自颜色的影响就越大。

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color Inverse '45,45 red  55,55 lime' \
          -colorspace sRGB  -fill white -stroke black \
          -draw 'circle 45,45 45,47  circle 55,55 55,57' \
          sparse_inverse_near.png
  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color Inverse '30,30 red  70,70 lime' \
          -colorspace sRGB  -fill white -stroke black \
          -draw 'circle 30,30 30,32  circle 70,70 70,72' \
          sparse_inverse_far.png

[IM 输出] [IM 输出]

另外,如果你“重叠”(完全堆叠或彼此非常靠近地放置)某些具有相同或相似颜色的点,你可以使该颜色的点强度增加两倍。 |

  magick -size 100x100 xc: -colorspace RGB \
          -sparse-color Inverse '30,30 red  75,65 lime  65,75 lime' \
          -colorspace sRGB -fill white -stroke black \
          -draw 'circle 30,30 30,32  circle 75,65 75,67  circle 65,75 65,77 '
\
          sparse_inverse_stronger.png

[IM 输出]
这些效果也适用于“[Shepards](#shepards)”方法!

Shepards 幂因子

ShepardsInverse 稀疏颜色方法实际上是相同的,只是应用于反距离加权的“幂级别”不同(分别为 2.0 和 1.0)。IM 从 v6.8.0-10 开始,你可以使用运算符 define 'shepards:power' 设置 '[Shepards](#shepards)' 方法使用的这个幂级别。例如

  magick -size 100x100 xc: -colorspace RGB -define shepards:power=0.5 \
     -sparse-color Shepards '30,10 red  10,80 blue  70,60 lime  80,20 yellow'
\
     -colorspace sRGB -fill white -stroke black \
     -draw 'circle 30,10 30,12  circle 10,80 10,82' \
     -draw 'circle 70,60 70,62  circle 80,20 80,22' \
     sparse_shepards_pow0.5.png
  magick -size 100x100 xc: -colorspace RGB -define shepards:power=1 \
     -sparse-color Shepards '30,10 red  10,80 blue  70,60 lime  80,20 yellow'
\
     -colorspace sRGB -fill white -stroke black \
     -draw 'circle 30,10 30,12  circle 10,80 10,82' \
     -draw 'circle 70,60 70,62  circle 80,20 80,22' \
     sparse_shepards_pow1.png
  magick -size 100x100 xc: -colorspace RGB -define shepards:power=2 \
     -sparse-color Shepards '30,10 red  10,80 blue  70,60 lime  80,20 yellow'
\
     -colorspace sRGB -fill white -stroke black \
     -draw 'circle 30,10 30,12  circle 10,80 10,82' \
     -draw 'circle 70,60 70,62  circle 80,20 80,22' \
     sparse_shepards_pow2.png
  magick -size 100x100 xc: -colorspace RGB -define shepards:power=3 \
     -sparse-color Shepards '30,10 red  10,80 blue  70,60 lime  80,20 yellow'
\
     -colorspace sRGB -fill white -stroke black \
     -draw 'circle 30,10 30,12  circle 10,80 10,82' \
     -draw 'circle 70,60 70,62  circle 80,20 80,22' \
     sparse_shepards_pow3.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=8 \
     -sparse-color Shepards '30,10 red  10,80 blue  70,60 lime  80,20 yellow'
\
     -colorspace sRGB -fill white -stroke black \
     -draw 'circle 30,10 30,12  circle 10,80 10,82' \
     -draw 'circle 70,60 70,62  circle 80,20 80,22' \
     sparse_shepards_pow8.png

[IM 输出]
幂 0.5 | [IM 输出]
幂 1.0
(Inverse)| [IM 输出]
幂 2.0
(Shepards)| [IM 输出]
幂 3.0 | [IM 输出]
幂 8.0
---|---|---|---|---

正如你所看到的,“色点”从非常尖锐的点扩散到圆点,再到大面积的颜色。在非常高的幂次下,它最终会再现与 Voronoi 稀疏颜色方法 相同的图案。此 -define 不仅影响 Shepards 稀疏颜色,还会影响基于稀疏颜色方法生成的计算位移图的 Shepards 扭曲方法。也有类似的效果。但是,它不会影响 Inverse 稀疏颜色方法,该方法始终使用 1.0 的幂次。

稀疏颜色方法总结

这里再次列出各种 4 点“[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)”图像,以便比较。 [IM 输出]
Voronoi | [IM 输出]
Voronoi(模糊)| [IM 输出]
Shepards | [IM 输出]
逆 | [IM 输出]
Bilinear
---|---|---|---|---
以及各种三点方法的总结。 [IM 输出]
Voronoi | [IM 输出]
Voronoi(模糊)| [IM 输出]
Shepards | [IM 输出]
逆 | [IM 输出]
Barycentric
---|---|---|---|---
目前,只有“[Voronoi](#voronoi)”、“[Shepards](#shepards)”和“[Inverse](#inverse)”方法适用于 4 个以上的点。 _更多“[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)”方法正在计划中。如果你有任何想法,请给我发电子邮件。 _

通道和稀疏颜色

[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)”运算符受“[-channel](https://imagemagick.org/command-line-options/#channel)”设置影响,这意味着你可以用该设置把它的效果限制到单个通道,或扩展到透明度通道。你还可以使用“[-channel](https://imagemagick.org/command-line-options/#channel)”设置,只在一个通道上操作以加速灰度图像处理,然后再“[-separate](https://imagemagick.org/command-line-options/#separate)”该通道(更多细节见通道处理)。例如.. |

  magick -size 100x100 xc: -channel G -sparse-color Shepards \
              '30,10 gray70  10,80 black  70,60 white  80,20 gray(33.3333%)' \
          -separate +channel    -fill white -stroke black \
          -draw 'circle 30,10 30,12  circle 10,80 10,82' \
          -draw 'circle 70,60 70,62  circle 80,20 80,22' \
          sparse_shepards_gray.gif

[IM 输出]
截至 IM v6.6.8-5,未修改的通道会被保留,因此你现在可以把 稀疏颜色 与“[-channel](https://imagemagick.org/command-line-options/#channel)”设置结合起来,快速、轻松地给任何图像添加透明渐变。例如,这里我添加一个透明的对角渐变,并让 50% 透明度沿内置“rose:”图像的对角线分布。 |

  magick rose: -alpha set -channel A \
          -sparse-color Barycentric \
                 '0,0 opaque   %w,-%h opaque    %w,%h transparent' \
          rose_alpha_gradient.png

[IM 输出]
| 颜色“Opaque”只是“Black”的另一个名称。基本上,当你真正关心的只是指定一种完全不透明的颜色,而实际颜色本身并不重要时,就会使用它。颜色“Transparent”也是如此;也可以分别使用“White”和“None”。
---|---
| IM 在 v6.6.8-5 之前,“[-channel](https://imagemagick.org/command-line-options/#channel)”设置中未选择的通道将重置为零(黑色)值。这严重限制了它的有效用途。
---|---
稀疏颜色 还接受标准化浮点值来代替颜色名称。你需要提供来替换颜色名称的值的数量取决于当前的“[-channel](https://imagemagick.org/command-line-options/#channel)”设置以及该通道在正在处理的图像中是否处于“活动”状态。最简单的是将处理限制为单个通道。另请注意,当使用原始数字而不是颜色名称时,透明度值是(在 IMv7 中)“matte”(遮罩)值(0 = 不透明)而不是“alpha”值(1 = 不透明)。因此,我们可以在上面使用数字代替颜色名称

  -channel A  -sparse-color Bilinear '0,0 1.0   -%w,%h 1.0    %w,%h 0.0'

使用可能无法访问“颜色名称”翻译功能的编程脚本或 API 可能更容易处理此问题。

稀疏颜色作为填充运算符

创建稀疏颜色运算符的最初原因之一是能够给出仅包含少量固定颜色点的图像,我们可以从中“填充”剩余的未定义颜色。例如,这里我画了少量的像素。我专门禁用了“[+antialias](https://imagemagick.org/command-line-options/#antialias)”设置,以避免绘制半透明或混合颜色,因此图像仅包含你指定的四种颜色,而没有其他颜色。 |

  magick -size 100x100 xc:none +antialias -fill none -strokewidth 0.5 \
          -stroke Gold        -draw "path 'M 20,70  A 1,1 0 0,1 80,50'" \
          -stroke DodgerBlue  -draw "line 30,10  50,80" \
          -stroke Red         -draw "circle 80,60  82,60" \
          sparse_source.gif

[IM 输出]
现在,我们可以提取该图像中存在的少数非透明像素,并使用多点稀疏颜色方法“[Shepards](#shepards)”填充所有其他颜色。 |

  magick sparse_source.gif sparse-color:- |\
      magick sparse_source.gif -alpha off \
              -sparse-color shepards '@-' sparse_fill.png

[IM 输出]
上面的“sed”命令读取枚举文本文件格式,删除第一行头部以及任何包含透明度的行,然后把它重新格式化为像素坐标和颜色列表。随后通过特殊的“@-”参数,把该列表通过管道传给稀疏颜色运算符。是的,上面的方法非常棘手,但确实有效,至少对于数量很少的点来说如此。不过提供的点越多,操作就越慢。这是因为稀疏颜色在处理上是“点”导向的,而不是面向图像或形态学的。最终我希望能提供一组面向形态学的“孔洞填充”方法,让你直接给出上面的图像,并让它自动填充透明区域。这种点提取技术可以与 EdgeIn 形态学方法结合,提取对象或孔洞边缘周围的像素,然后“填入”缺失的背景或孔洞(如形态学与通道所示)。例如...

  magick figure.gif -channel A -morphology EdgeIn Diamond
shape_edge_pixels.gif
  magick shape_edge_pixels.gif txt:- |\
    sed '1d; / 0) /d; s/:.* /,/;' | \
     magick shape_edge_pixels.gif -alpha off \
             -sparse-color shepards '@-' shape_edge_in_lights.png
  magick shape_edge_in_lights.png figure.gif -composite shape_in_lights.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出]

请注意,生成的图像与输入完全相同,但透明背景已替换为距离模糊的“边缘颜色”。这就是图像边缘模糊的原因。该图像是专门为了尝试产生更好的“羽化”技术而开发的。其他羽化方法请参见模糊羽化距离羽化

稀疏颜色 Shepards,模糊替代方案

使用“[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)”的一种替代方法,是取透明背景上的像素图像并对其进行模糊,然后丢弃透明度。

  magick sparse_source.gif   -channel RGBA -blur 0x15 \
          -alpha off  sparse_blur_simple.png

[IM 输出] [IM 输出]

这样做的问题是原始颜色没有被保留,并且存在一个到底使用哪个“sigma”值的问题。它还没有考虑每种颜色的“接近”程度,因此两个靠近的彩色像素(比“sigma”值更接近)将相互淹没,从而模糊并混合在一起。
更好的方法是生成多层模糊图像,其“sigma”值逐渐变小,原始未模糊图像位于顶部。

  for sigma in  64 32 16 8 4 2 1 0;  do
    magick sparse_source.gif -depth 16 \
            -channel RGBA -blur 0x$sigma miff:-
  done |
    magick - -background none -flatten -alpha off sparse_blur_layered.png

[IM 输出] [IM 输出]

这种分层模糊方法相当于同一图像上“[Shepards](#shepards)”方法的结果。虽然不准确,但非常接近。然而,如果涉及大量输入像素,它可能会快得多,因为它是面向图像(形态学)的,而不是使用单个点进行计算。另一种分层模糊方法是使用调整尺寸生成模糊图像的“金字塔”。 使用调整尺寸进行大模糊 中详细解释了该技术。 |

  magick sparse_source.gif \
          \( +clone -resize 50% \) \
          \( +clone -resize 50% \) \
          \( +clone -resize 50% \) \
          \( +clone -resize 50% \) \
          \( +clone -resize 50% \) \
          \( +clone -resize 50% \) \
          \( +clone -resize 50% \) \
          -layers RemoveDups -filter Gaussian -resize 100x100\! -reverse \
          -background None -flatten -alpha off    sparse_blur_pyramid.png

[IM 输出]
这种方法即使处理非常大的图像也会很快,因为不需要在每个模糊步骤中使用很大的“sigma”值(那会非常慢)。本质上,它使用更快的图像调整尺寸技术来生成上一个示例中的模糊层。它没有那么精确,但会生成对正确结果的良好近似。不过,它最适合正方形且尺寸为 2 的幂的图像,否则精度会降低。上面的特殊运算符“[-layers](https://imagemagick.org/command-line-options/#layers) RemoveDups”会移除多个“clone-resize”操作生成的额外“单个平均像素”图像。随后使用Gaussian 调整尺寸滤镜(相当于模糊)把图像调整回原始大小。然后反转图像顺序,把原始图像放在最上方,把更模糊的图层放在下面,再像之前一样扁平化在一起。它的优点是只需读取图像一次,就能在单个命令中完成所有工作。即使对大图像也非常快,尤其因为每一步调整尺寸只把图像减半,从而避免了使用极大 sigma 进行缓慢模糊。这个方法唯一的缺点是,你需要大致了解原始图像大小,以便恢复“模糊”图像,并至少粗略估计要生成多少个调整尺寸克隆(最大尺寸的 Log2 加 1)。不过,过多生成调整尺寸克隆不会带来严重性能损失,因为当输入图像已经调整到最小的 1 像素图像时,调整尺寸会变成“no-op”。多余且无用的“调整尺寸图像层”随后会用“[-layers](https://imagemagick.org/command-line-options/#layers) RemoveDups”自动处理。唯一真正的问题,是处理尺寸不是 2 的幂的图像时,调整尺寸后的图像可能会变得“不同步”。这个问题有多严重还不清楚,但应该不会太严重,因为这些图像也最为模糊。当然,它仍然存在“[Shepards](#shepards)”方法的“泄漏”问题,所以让我们更详细地看看这个问题。

Shepards 方法的“泄漏”

'[Shepards](#shepards)' 方法不了解“边界”,因此某条“颜色线”远侧的颜色会越过这条线泄漏,或“渗透”过去。最终,在足够远的距离处,你会得到所有像素的纯平均颜色。这并不总是想要的结果(尽管某些情况下确实有用)。在这个示例中,“Red”曲线越接近“White”线,颜色就越会“泄漏”穿过两条线到达远侧,产生粉红色。 |

  magick -size 100x100 xc:none +antialias -fill none -strokewidth 0.5 \
          -stroke Red    -draw "path 'M 26,0  A 55,61 0 0,1 26,100'" \
          -stroke White  -draw "line 50,0  50,100" \
          sparse_lines_near_source.gif

[IM 输出]
|

  magick sparse_lines_near_source.gif txt:- |\
    sed '1d; / 0) /d; s/:.* /,/;' |\
      magick -size 100x100 xc: -sparse-color shepards '@-' \
              sparse_lines_near.png

[IM 输出]
当使用Shepards方法“填充孔”时,尤其是涉及多个孔时,这种颜色泄漏是主要问题。这是因为与一个孔相关的颜色可能会泄漏到并影响完全不同的孔的颜色(反之亦然)。了解边界是 Shepards 方法 与另一种形式的颜色“填空”(称为“颜色扩散”)的区别。基本上在颜色扩散中,颜色不能穿过其他定义颜色的线条。这是通过将效果限制为仅“视线”内的颜色或泄漏到边缘外侧来实现的。这需要使用到最近颜色的距离来限定哪些颜色影响像素。 扩散曲线 网站上介绍了“颜色扩散”的一项主要用途。它不仅广泛使用颜色扩散,而且还包含有关快速生成扩散的技术的信息。我希望有一天能在 ImageMagick 中实现这一点


等离子图像

等离子渐变

虽然渐变提供了平滑的颜色范围,但另一个图像创建运算符“plasma:”提供了另一种渐变。它非常适合为图像生成随机的彩色背景。首先要指出,“plasma:”是随机图像,因此每次运行都可以、也确实会生成不同的图像。例如,这里我们生成三张独立的“标准”等离子图像,尽管使用的是同一条命令,每张图像都彼此不同。

  magick -size 100x100  plasma:  plasma1.jpg
  magick -size 100x100  plasma:  plasma2.jpg
  magick -size 100x100  plasma:  plasma3.jpg

[IM 输出] [IM 输出] [IM 输出]

你还可以看到,等离子图像是一种随机颜色渐变,从顶部白色开始,底部黑色,类似于“gradient:”。尽管没有很好的记录,你可以以与上面的线性渐变完全相同的方式指定等离子渐变的颜色。

  magick -size 100x100  plasma:blue              plasma_range1.jpg
  magick -size 100x100  plasma:yellow            plasma_range2.jpg
  magick -size 100x100  plasma:green-yellow      plasma_range3.jpg
  magick -size 100x100  plasma:red-blue          plasma_range4.jpg
  magick -size 100x100  plasma:tomato-steelblue  plasma_range5.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

你还可以看到,“tomato”和“steelblue”等中间调颜色往往比“red”和“blue”等纯色效果更好。通过使用相同的颜色两次,你可以生成以该颜色为主的背景,但具有接近原始颜色的随机颜色点。

  magick -size 100x100  plasma:black-black          plasma_black.jpg
  magick -size 100x100  plasma:grey-grey            plasma_grey.jpg
  magick -size 100x100  plasma:white-white          plasma_white.jpg
  magick -size 100x100  plasma:yellow-yellow        plasma_yellow.jpg
  magick -size 100x100  plasma:tomato-tomato        plasma_tomato.jpg
  magick -size 100x100  plasma:steelblue-steelblue  plasma_steelblue.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

同样,正如你所看到的,中间色调在生成的图像中比黑色、白色和黄色等极端颜色产生更多的颜色变化。上面显示的“grey”等离子特别漂亮,具有虹彩“珍珠母”效果。基本上,这是因为灰色给了“plasma:”生成颜色的完全自由度。 对完美的 50% 灰度等离子进行归一化,会得到一种特别均匀的多色等离子图像,覆盖包括白色和黑色在内的整个色彩范围。 |

  magick -size 100x100  plasma:grey50-grey50 -auto-level plasma_grey_norm.jpg

[IM 输出]
或者,你可以扩大颜色对比度并使颜色大胆,但不要太极端。 |

  magick -size 100x100  plasma:grey50-grey50 \
                       -sigmoidal-contrast 8x50%   plasma_grey_contrast.jpg

[IM 输出]
将此图像与下面的“分形等离子”图像进行比较。

分形等离子

等离子生成器还具有特殊的分形模式,可产生高度多彩的效果。生成的颜色会被增强,从而产生更夸张的颜色变化。

  magick -size 100x100  plasma:fractal  plasma_fractal1.jpg
  magick -size 100x100  plasma:fractal  plasma_fractal2.jpg
  magick -size 100x100  plasma:fractal  plasma_fractal3.jpg

[IM 输出] [IM 输出] [IM 输出]

事实上,这与我们已经看到的恒定颜色等离子图像非常相似,而且实际上它们是以相同的方式产生的,但具有更明显的颜色变化。
我经常发现等离子图像有点“嘈杂”。因此,使用“[-blur](https://imagemagick.org/command-line-options/#blur)”稍微平滑一下通常会有帮助。 在这里,我把上面中间那幅等离子图像中的噪声平滑掉了。 |

  magick plasma_fractal2.jpg  -blur 0x2  plasma_smooth.jpg

[IM 输出]
你可以使用“[-paint](https://imagemagick.org/command-line-options/#paint)”来创建随机颜色污渍。 |

  magick plasma_fractal2.jpg  -blur 0x1 -paint 8  plasma_paint.jpg

[IM 输出]
也可以先使用 "[-emboss](https://imagemagick.org/command-line-options/#emboss)" 图像运算符让颜色更鲜明、更接近圆形;在此之前,用 "[-blur](https://imagemagick.org/command-line-options/#blur)" 去除低层噪声。 |

  magick plasma_fractal2.jpg  -blur 0x5 -emboss 2 plasma_emboss.jpg

[IM 输出]
如果你使用“[-blur](https://imagemagick.org/command-line-options/#blur)”后跟“[-sharpen](https://imagemagick.org/command-line-options/#sharpen)”,则可以生成比“[-emboss](https://imagemagick.org/command-line-options/#emboss)”具有更多柔和颜色的图案。 |

  magick plasma_fractal2.jpg  -blur 0x5 -sharpen 0x15 plasma_sharp.jpg

[IM 输出]
事实上,我发现旋转后的等离子渐变特别适合作为背景图案。 |

  magick -size 160x140  plasma:fractal \
          -blur 0x2  -swirl 180  -shave 20x20  plasma_swirl.jpg

[IM 输出]

灰度等离子

现在,即使输入是纯黑色的单色,等离子生成器也始终会产生颜色。不过,我们经常需要生成纯灰度的等离子图像。有两种简单的方法可以做到这一点。 最简单的方法是取一幅等离子图像,并将其转换为灰度图像。 |

  magick -size 100x100 plasma:fractal -blur 0x2 \
          -colorspace Gray   plasma_greyscale.jpg

[IM 输出]
另一种方法是将其中一个颜色通道复制到另外两个颜色通道,以获得更强的单层效果。 |

  magick -size 100x100 plasma:fractal -blur 0x2 \
          -channel G -separate   plasma_grey_copy.jpg

[IM 输出]
最后一种技术是对等离子图像使用“[-shade](https://imagemagick.org/command-line-options/#shade)”。 |

  magick -size 100x100 plasma:fractal -blur 0x5 \
          -shade 120x45  -auto-level  plasma_grey_shade.jpg

[IM 输出]
你可能会期待得到许多光影效果,但由于原始等离子图像过于随机,“[-shade](https://imagemagick.org/command-line-options/#shade)”似乎只会产生更多“斑驳等离子”效果。与其使用颜色变化非常夸张的分形等离子,不如使用恒定颜色等离子方法创建灰度等离子。作为副作用,这种方法还能控制生成的灰度等离子图像的整体亮度。

  magick -size 100x100 plasma:black-black \
           -blur 0x2 -colorspace Gray plasma_grey0.jpg
  magick -size 100x100 plasma:grey25-grey25 \
           -blur 0x2 -colorspace Gray plasma_grey1.jpg
  magick -size 100x100 plasma:grey50-grey50 \
           -blur 0x2 -colorspace Gray plasma_grey2.jpg
  magick -size 100x100 plasma:grey75-grey75 \
           -blur 0x2 -colorspace Gray plasma_grey3.jpg
  magick -size 100x100 plasma:white-white   \
           -blur 0x2 -colorspace Gray plasma_grey4.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

如果这还不够大胆,请使用通道复制方法对等离子图像进行灰度化。

  magick -size 100x100 plasma:black-black   \
          -blur 0x2  -channel G  -separate   plasma_grey5.jpg
  magick -size 100x100 plasma:grey25-grey25 \
          -blur 0x2  -channel G  -separate   plasma_grey6.jpg
  magick -size 100x100 plasma:grey50-grey50 \
          -blur 0x2  -channel G  -separate   plasma_grey7.jpg
  magick -size 100x100 plasma:grey75-grey75 \
          -blur 0x2  -channel G  -separate   plasma_grey8.jpg
  magick -size 100x100 plasma:white-white   \
          -blur 0x2  -channel G  -separate   plasma_grey9.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

这些灰度等离子图像对于进一步处理非常有用,并且可以生成其他图像效果。例如,查看背景图像页面。在那里你会发现大量使用分形等离子创建有趣效果的示例。

设定种子或重复生成等离子图像

请记住,“plasma:”可以产生近乎纯黑、近乎纯白或任何其他颜色的区域(尽管不太可能是完全纯色)。虽然不太可能得到整幅图像都是同一种颜色的结果,但这仍然可能发生。因此,当你得到一个好结果时,可能会想保存下来以便以后重用。也因此,使用等离子图像的脚本可能会希望包含生成并重用这类随机图像的选项。也就是说,你可能希望把等离子图像的生成,与使用该图像的其他部分分离,以便重用。 不过,更简单的技术是为 IM 随机数生成器“设定种子”或初始化,使“plasma:”生成相同的“随机”图像。这样你就可以调整脚本或程序,一次又一次产生良好或有趣的色彩或效果。 |

  magick -size 100x100 -seed 4321  plasma:    plasma_seeded.jpg

[IM 输出]
上图永远不会改变,因此右下角总会有一个“红色”区域,除非你更改“[-seed](https://imagemagick.org/command-line-options/#seed)”的值。有趣的是,使用具有不同初始化颜色渐变的相同种子可以生成具有相似内部图案的随机但相似的图像集。

  magick -size 100x100 -seed 4321 plasma:grey-grey         plasma_rnd1.jpg
  magick -size 100x100 -seed 4321 plasma:white-blue        plasma_rnd2.jpg
  magick -size 100x100 -seed 4321 plasma:green-yellow      plasma_rnd3.jpg
  magick -size 100x100 -seed 4321 plasma:red-blue          plasma_rnd4.jpg
  magick -size 100x100 -seed 4321 plasma:tomato-steelblue  plasma_rnd5.jpg

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

如你所见,上面所有图像中都存在相同的颜色图案,但底层颜色基调有时会强调或掩盖某些共享图案。最后还要注意一点:其他 IM 运算符也会使用随机数生成器,例如“[-fx](https://imagemagick.org/command-line-options/#fx)”中的“rand()”函数、“[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)”中的“random”设置、“[-random-threshold](https://imagemagick.org/command-line-options/#random-threshold)”抖动运算符,以及“[-noise](https://imagemagick.org/command-line-options/#noise)”运算符等。因此,最好在具体使用生成器之前先设定随机数生成器的种子。IM 从 v6.3.4-3 开始,还可以使用“[+seed](https://imagemagick.org/command-line-options/#seed)”重新随机化生成器。因此,把这个设置放在已设定种子的等离子图像之后,就能确保后续运算符按你的意愿产生真正随机的结果。默认情况下,IM 启动时会随机化种子,因此通常不需要自己用“[+seed](https://imagemagick.org/command-line-options/#seed)”来随机化,就能得到随机结果。

使用等离子时的问题

使用“plasma:”图像要避免的一个问题是生成高宽高比的图像。这会扭曲正常的等离子颜色效果,并倾向于将颜色拉伸成针状条纹。

  magick -size 200x50 plasma:  plasma_high_aspect.jpg

[IM 输出]

对此没有简单的解决方案,因此除非这正是你想要的效果,否则需要谨慎。等离子图像还存在明显的从左上到右下的对角线扭曲,而这本不应该出现。换句话说,该算法存在某种“空间偏差”缺陷。例如,正如 Thomas Maus 所指出的,如果镜像并连接同一幅等离子图像,你总会在生成的图像中看到明显的“V”。

  magick -size 60x60 plasma: \( +clone -flop \) +append plasma_flaw.jpg

[IM 输出]

这本不应该发生。但这个问题似乎太深,如果不基本上完全重写整个等离子生成器函数,就无法解决。


随机图像

原始随机噪声

IM 从 v6.3.5 开始,你可以使用噪声生成器“[+noise](https://imagemagick.org/command-line-options/#noise)”的“Random”方法从现有图像生成纯随机图像。 |

  magick -size 100x100 xc:   +noise Random   random.png

[IM 输出]
如果你的 IM 比这个旧,你仍然可以使用较慢的 DIY FX 运算符[-fx](https://imagemagick.org/command-line-options/#fx)”生成纯随机噪声图像。 |

  magick -size 100x100 xc: -fx 'rand()'   random_fx.png

[IM 输出]
或者为了提高速度,你可以使用“[-spread](https://imagemagick.org/command-line-options/#spread)”运算符来随机化渐变(分别针对三个颜色通道)或其他图像。 |

  magick -size 100x100 gradient: -separate \
          -virtual-pixel tile   -spread 200   -combine  random_spread.png

[IM 输出]
结果可能看起来非常随机,但它们会产生更受控制的颜色范围(或简单的颜色值)。

随机点(像素灰尘)

生成由随机像素分散组成的图像也很有用。只要记住,随机图像的三个 颜色通道 中,每一个都可以看作独立的随机灰度图像,而这些通道又可以用各种方式合并在一起。 例如,可以先对一个颜色通道('G',即绿色通道)做 阈值化,再将其分离为灰度图像,从而生成随机点的掩模。 |

  magick random.png  -channel G -threshold 5% -separate \
          +channel -negate    random_mask.png

[IM 输出]
由于每种颜色都是线性随机值,因此上面使用的阈值百分比会直接定义被选中像素的密度。你还可以进一步使用一个颜色通道('G',即绿色通道)作为选择依据,通过各种 图像合成 方法,从另一个颜色通道('R',即红色通道)中选取随机值。

  magick random.png   -channel G -threshold 5% -negate \
          -channel RG -separate +channel \
          -compose Multiply    -composite   random_black.png
  magick random.png   -channel G -threshold 5% \
          -channel RG -separate +channel \
          -compose Screen      -composite   random_white.png
  magick random.png   -channel G -threshold 5% -negate \
          -channel RG -separate +channel \
          -compose CopyOpacity -composite   random_trans.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出]

这些类型的图像可以直接用于生成闪光动画。然而,进一步的处理,尤其是在黑色背景版本上,可以根据灰度强度放大这些点,或者从这些点生成条纹和星状耀斑。有关示例,请参阅 星形生成器。 与种子等离子图像类似,你也可以使用“[-seed](https://imagemagick.org/command-line-options/#seed)”设置预初始化随机数生成器。这样就可以在特定机器上重复生成相同的随机图像,就像等离子图像一样。

模糊的随机图像(随机斑点)

现在,你还可以直接使用随机图像来创建斑点效果,但纯粹的随机图像通常不太有用。然而,通过模糊纯随机图像,我们可以引入某种“邻域”顺序,以便附近的像素相关。例如,这里我们模糊一张随机图像,以便随机值产生更大的“斑点”或斑驳的颜色。

  magick random.png -virtual-pixel tile  -blur 0x1  -auto-level  random_1.png
  magick random.png -virtual-pixel tile  -blur 0x3  -auto-level  random_3.png
  magick random.png -virtual-pixel tile  -blur 0x5  -auto-level  random_5.png
  magick random.png -virtual-pixel tile  -blur 0x10 -auto-level
random_10.png
  magick random.png -virtual-pixel tile  -blur 0x20 -auto-level
random_20.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

但请注意,如果没有虚拟像素设置,“[-blur](https://imagemagick.org/command-line-options/#blur)”运算符具有很强的边缘效果。最好避免这种情况。作为奖励,通过将“[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)”设置更改为“tile”,随机图像将保持可平铺,并且颜色将环绕图像边界。这种平铺能力目前对于随机等离子图像 是不可能的,并且是纯随机图像一开始就非常随机的固有结果。 模糊随机色调 对于模糊随机噪声图像,我最喜欢的变换之一是将值映射到 HSB 色调。 |

  magick random_10.png -set colorspace HSB \
          -channel GB -evaluate set 100% +channel \
          -colorspace RGB random_hues_cyan.png

[IM 输出]
上述问题在于,模糊往往会产生红黄色(低值)和红洋红色(高值)的斑点,中间夹着绿色、青色和蓝色的条带。这只是色相值被模糊并重新拉伸后的结果。理想的解决方案是一种会考虑色相值循环性质的模数模糊。不过这样的运算符目前并不存在,也许以后也不会有。 我所知道的最佳解决方案,是简单地把图像中的三个随机通道全部相加(使用模数相加合成),从而扩展数值范围。这也会带来一个副作用,让模糊斑点变小,但至少你现在能得到动态范围更宽的彩虹色。 有人有更好的主意吗? |

  magick random_10.png -separate -background white \
          -compose ModulusAdd -flatten -channel R -combine +channel \
          -set colorspace HSB -colorspace RGB random_hues.png

[IM 输出]
有关处理随机图像的更多方法,请参阅上面的等离子图像生成背景 模糊随机灰色 正如你在上面所看到的,你将获得带有不同原色斑点的图像。这是因为每个通道都作为灰度图像完全独立地处理。让我们提取上面每张图像的一个通道,看看模糊图像的结构。

  magick random.png     -channel G  -separate   random_0_gray.png
  magick random_1.png   -channel G  -separate   random_1_gray.png
  magick random_3.png   -channel G  -separate   random_3_gray.png
  magick random_5.png   -channel G  -separate   random_5_gray.png
  magick random_10.png  -channel G  -separate   random_10_gray.png
  magick random_20.png  -channel G  -separate   random_20_gray.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

你首先应该注意到,图像通常(但并不总是)会包含大致相等数量的黑色和白色区域。如果我们以 50% 对随机图像进行 阈值处理,就能看到这一点

  magick random_0_gray.png   -threshold 50%   random_0_thres.png
  magick random_1_gray.png   -threshold 50%   random_1_thres.png
  magick random_3_gray.png   -threshold 50%   random_3_thres.png
  magick random_5_gray.png   -threshold 50%   random_5_thres.png
  magick random_10_gray.png  -threshold 50%   random_10_thres.png
  magick random_20_gray.png  -threshold 50%   random_20_thres.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

正如你所看到的,你会得到大约 50% 的白色和 50% 的黑色区域,由一条曲线分隔开。此外,这条线的弯曲程度根据用于模糊纯随机图像的“sigma”值而变化。从单个像素产生黑白“雪”的图像到图像非常均匀(但仍然随机)分为两个黑白区域的图像。有关使用随机图像的更多示例,请参阅背景图像,或者有关生成随机画布的更多示例,请参阅纯色随机点

随机粒度(混乱中的秩序)

现在,请记住,模糊的随机图像都是从同一个初始随机图像生成的,因此它们都是相关的。然而,每个新生成的随机图像将具有完全不同的图案。然而,这些模式在结构上看起来或多或少相似。 首先,让我们给出一个从头开始生成“模糊随机图像”的完整示例... |

  magick -size 100x100 xc:  -channel G +noise Random \
         -virtual-pixel Tile -blur 0x5 -auto-level \
          -separate +channel   random_5_gray.png

[IM 输出]
大量使用“[-channel](https://imagemagick.org/command-line-options/#channel)”设置,把操作限制在图像的“绿色”通道上,这一点很重要,因为它能让整幅图像的生成速度提高约三倍。 通道分离 随后会确保得到纯灰度结果。如果你愿意,也可以省略这两个“[-channel](https://imagemagick.org/command-line-options/#channel)”设置;这样会生成 3 幅完全独立且彼此不同的“模糊随机图像”。这幅图像有一些重要特征。如果把图像分成三组相等的颜色(使用称为色阶分离 的技术),这些特征会看得更清楚:在每个黑白区域内,可以看到更多圆形斑点或“颗粒”。 例如... |

  magick random_5_gray.png  -ordered-dither threshold,3  random_5_blobs.png

[IM 输出]
我首先想指出的是,图像中的亮区和暗区数量大致相等,但这些区域通过亮区和暗区之间形成的灰色“中间”渐变相互连接。图像中的各个斑点或“颗粒”会随区域而变化,但它们的平均直径大约是用于模糊初始随机图像的数值的 3 到 4 倍。这个模糊值被称为图像的粒度,是一个非常重要的值,因为它基本上代表了随机图像将生成的圆形结构的平均尺寸。有时也称为图像的“弯曲度”。值越高,图像中的这些曲线就越大、越缓。这是描述模糊随机图像最重要的因素,所以我们把它说清楚:

随机图像的“粒度”(或模糊因子)
决定内部圆形结构的尺寸

当然,“模糊系数”或“颗粒度”越小,曲线就会越小、越紧,当达到“0”值时,图像中所有的块和“斑点”都会消失,留下纯粹随机的“噪声”、“雪花”、“像素灰尘”之类的效果。
旁注:事实上,“颗粒”本身的大小可能会根据用于生成它们的阈值因子而变化。这个系数真正描述的是白色和黑色区域中心之间的平均距离。值越高,距离越大,并且斑点必须更大且更分散以适应增加的距离。当你开始查看下面的随机波纹 时,这一点会变得更加明显。
你可能还想尝试使用 50% 曝光过度/Solarize 操作,再配合一些额外的 等级调整,从图像中提取分离良好的黑白颗粒。 例如,下面是一个完整示例:粒度为 '8',斑点阈值为 '25%',从图像的黑色和白色部分都生成白点。 |

  magick -size 100x100 xc: -channel G +noise random \
          -virtual-pixel tile -blur 0x8 -auto-level  \
          -solarize 50% -separate +channel \
          -threshold 25% -negate   random_granules.png

[IM 输出]
请注意,随着该值的增加,生成模糊随机图像所需的时间也变得非常非常长。此外,当该值达到最小图像尺寸的大约一半时,随着随机图像稳定为单个白点和黑点,效果会停止增加。不建议使用较大的值。 [IM 输出] 总之,左边是一个巡逻循环动画,它是通过改变单个随机图像的“粒度”(随机模糊)而产生的。该动画是使用 shell 脚本“[animate_granularity](../static/img/canvas/animate_granularity)”生成的。你可以下载它、研究它并使用它。请注意,由于我们使用相同的随机图像作为源,因此“颗粒”或斑点实际上并没有移动太多,但似乎只是聚集在一起并消失,随着颗粒尺寸的增加而产生更大的“颗粒”。另外,请记住,尽管动画中的颜色数量有所减少,但完全随机图像的结构实际上是两组白色和黑色颗粒之间的平滑渐变。这种渐变使得图像可用于其他技术。

随机通量(动画循环)

现在,正如我们在上面看到的,颗粒和斑点实际上并没有移动那么多。但是,对于动画效果,你需要一种随时间平滑移动的图案。此外,如果图案只是来回移动也是不够的。最后,当动画循环时,你不希望图案突然跳跃或弹跳。我们需要某种方法来生成平滑重复的随机模式。这是一个艰巨的任务。它还需要平滑,因此所有图案必须从同一个随机图像生成。这是一个可以生成这种随机模式的想法。不要将每个随机像素值视为随机强度,而是将该值视为定义该像素处于最大或最小强度的“时间”值。换句话说,该值被转换为“波浪”上的位置。因此,每个像素代表正弦曲线的某个“相位”。这听起来很复杂,但事实并非如此。只需使用随机图像作为正弦函数的源图像。对于时间序列中的每个图像,为该时间周期内的特定点设置时间“相位

  magick random.png   -function Sinusoid 1,_{time}_ \
          ... do granular blurring,  and other processing ...

这里,“_{time}_”在一个完整的动画周期中从“0”更改为“360”。结果,你得到的像素不再是具有“静态”随机值,而是随着时间的推移在黑色和白色之间循环。每个像素都遵循相同的周期,但每个像素具有完全不同的“相位”,因此它独立于所有其他像素进行周期。也就是说,图像仍然是随机的,但随着给定的“时间”值平滑变化。对于有科学头脑的人来说,这有点像观察亚原子水平上存在的“量子涨落”。那里的空间远非正常尺度下的“静态”状态。这就是“随机通量”这个名字的由来。例如,让我们生成 12 张图像的时间序列

  for i in `seq 0 30 359`; do
    magick random.png  -channel G  -function Sinusoid 1,${i} \
            -virtual-pixel tile -blur 0x8 -auto-level \
            -separate flux_${i}.png
  done

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]
[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

现在,一幅随机图像就可以生成一整组形成循环的序列图像。请注意,“时间”提取必须在任何其他处理(例如模糊)之前进行,而这很可能是整个生成过程中最慢的部分。另一点值得注意的是,在相位 '180'(右下)处,实际得到的是第一张图像(左上)的精确负片:也就是“白色”颗粒变成“黑色”颗粒,反之亦然。事实上,动画的整个后半部分就是前半部分的负片。这可以用来缩短简单“随机通量”动画的生成时间。因为图像在 180 度相位处为负片,所以你会看到每个“白色”颗粒缓慢移动,仿佛要和相邻的“黑色”颗粒交换位置。但由于整个后半部分都是前半部分的负片,它不能只是简单地来回晃动,而必须继续向前运动,最终回到原图,或者绕成循环,或者适当地淡出再出现。换句话说,白色和黑色颗粒的运动周期要复杂得多。 [IM 输出] 右侧是上述帧的动画。波动图案完全随机,但会在帧与帧之间以及动画循环时平滑变化。你看不出结果的开始或结束。有时会看到旋转的运动,有时又像是所有“气体”般的斑点都被吸入暗区,或者只是出现后又淡出。它也会经历运动非常快和非常慢的时期,完全随机。 总之:这段动画同样具备 模糊的随机图像 中的那些属性。图像仍大致分成白色和黑色两部分,并形成约为图像模糊值或 粒度 三倍 大小的斑点。除此之外,由于循环的一半是另一半的负片,因此还能保证图像的所有部分都会在较浅和较深的颜色之间形成某种循环。你可能没有注意到的一点是,将随机线性值转换为正弦波形后,黑白颜色分离(对比度)会更清晰。因此,你也许会想利用 S 形对比 运算符的降对比能力,让生成图像不那么像“斑点”,并增强颗粒之间的渐变,而不是颗粒本身。现在,这只是循环随机动画用途的起点。随机图像 能做的一切,例如 生成背景 中描述的操作,也都可以应用到“随机通量动画”上。例如,我们先只显示“白色”颗粒的运动...... |

  magick flux_anim.gif -threshold 70% flux_thres_anim.gif

[IM 输出]
或者,生成一条变化的电丝,在图像上缓慢流动。 |

  magick flux_anim.gif  \
          -sigmoidal-contrast 30x50% -solarize 50% -auto-level \
          -set delay 20 filaments_anim.gif

[IM 输出]
请注意,由于循环的一半是前半部分的负片,并且我们使用 曝光过度/Solarize 将白色和黑色折叠到一起,因此这个循环实际上会在一个动画周期内重复两次。要消除其中一些非常快速的变化,确实需要更多帧。
为了使较长循环序列的运动难以预测,你还可以使用一些 渐变数学 组合来自多个随机图像的多个正弦循环,甚至仅使用同一随机图像的其他颜色通道。

未来:创造更不可预测且持久的“和谐”周期

随机涟漪

通过给 模糊的随机图像 再加一种变化,我们可以加入另一个复杂度层级,使这些图像更有用,并提供一个超出 粒度 之外的控制变量。但首先你需要记住,随机图像不仅包含明亮和黑暗区域,还包含这些区域之间的斜率。把这个斜率作为 正弦函数 的输入,就可以在图像中的斑点之间生成波纹。请注意,这种 正弦函数 用法与前面 随机通量 示例的关键区别在于,这一次函数是在图像经过模糊平滑之后(而不是之前)应用的。同样,在这种情况下,更重要的是“频率”值,而不是第二个“相位”值。例如...

  magick random_10_gray.png  -function Sinusoid 1,90   ripples_1.png
  magick random_10_gray.png  -function Sinusoid 2,90   ripples_2.png
  magick random_10_gray.png  -function Sinusoid 3,90   ripples_3.png
  magick random_10_gray.png  -function Sinusoid 4,90   ripples_4.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

正如你所看到的,正弦函数的“频率”越大,“颗粒”之间的渐变中添加的波纹就越多。'1' 的“频率”基本上会把源图像中的浅色和深色“斑点”都变成白色,并在它们之间留下深色间隙。'2' 的“频率”会在那个深色间隙中挤入额外的“脊”或“波纹”。随着频率增加,原始图像最亮和最暗区域之间会出现越来越多的“波纹”,使图像变得越来越复杂。随着脊的数量增加,你可能会看不出图像中原本的“斑点”或“颗粒”。可以在添加波纹之前先修改渐变来解决这个问题:用 色阶调整 裁切渐变,或者用 S 形对比 压缩中间调。这会给“颗粒”一定的质量或面积,从而在波纹之间提供“平静”区域。

  magick random_10_gray.png        -level 25%            random_enhanced.png
  magick random_enhanced.png  -function Sinusoid 4,90    ripples_4e.png
  magick random_10_gray.png   -sigmoidal-contrast 10,50% random_sigmoidal.png
  magick random_sigmoidal.png -function Sinusoid 4,90    ripples_4s.png

[IM 输出] [IM 输出] [IM 输出]
[IM 输出] [IM 输出]

两种方法各有优缺点,但本质上都是增大颗粒。然而,白色颗粒组和黑色颗粒组之间的距离并没有增加。当然,这样做的一个副作用是两组颗粒之间的波纹被压缩。
上例中使用的第二个值“90”是正弦函数的“相位”。这决定了源图像中的“黑色”颗粒在“波纹”图像中的颜色

  magick random_enhanced.png  -function Sinusoid 3,0     ripples_3e000.png
  magick random_enhanced.png  -function Sinusoid 3,90    ripples_3e090.png
  magick random_enhanced.png  -function Sinusoid 3,180   ripples_3e180.png
  magick random_enhanced.png  -function Sinusoid 3,270   ripples_3e270.png

[IM 输出] [IM 输出] [IM 输出] [IM 输出] [IM 输出]

“白色”颗粒的颜色取决于“相位”和所应用“频率”的小数部分。整数“频率”值会让白色和黑色颗粒的颜色一起变化(根据“相位”)。因此,当相位为“90”时,两者都是白色的。但是,如果应用小数“频率”值,例如“0.5”,则“白色源”颗粒(由“相位”确定)将是“黑色源”颗粒的负值。 |

  magick random_enhanced.png  -function Sinusoid 3.5,90    ripples_3.5e.png

[IM 输出]
请注意,对于“灰色”的“相位”角,一个颗粒会被白色环包围,另一个则会被黑色环包围。如果使用带有“0.5”小数部分的“频率”值,则每个斑点周围的第一圈波纹会根据所用“相位”变成全白或全黑。 | _不建议使用整数或“0.5”以外的“频率”,因为两组颗粒会以某种方式失去同步。

同样,除非你要生成“波纹动画”(如下所述),否则不建议使用 90 度倍数以外的相位。

生成“色散图”(如下)时,建议使用相位值“0”。这是为了最大限度地减少强调的“颗粒”区域内的失真。
---|---
与之前的随机通量 类似,“_相位
”可以随时间变化,以产生从一组颗粒移动到另一组颗粒的波纹动画。在没有对比度增强的情况下,这种方法效果特别好。 |

  for i in `seq 0 30 359`; do
    magick random_10_gray.png -function Sinusoid 3.5,${i} miff:-
  done |
    magick miff:- -set delay 15 -loop 0 ripples_anim.gif

[IM 输出]
旁注:上面使用的技术称为“管道式 MIFF:”,这是可行的,因为 MIFF:" 文件格式可以简单地把图像“串接”起来生成多图像文件。需要注意的一点是,这个动画看起来比上面创建的 通量动画 变化慢得多。也就是说,在一个动画周期内,波纹只会移动很短的距离;而在“通量”动画中,变化会在半个周期内从大尺度的白色颗粒传播到黑色颗粒,然后再返回。现在你可以把上面的波纹动画与来自同一随机图像源的底层“通量”动画组合起来,生成更加动态、流动的形式,但要注意动画速度的差异。例如,这里我只是取前面创建的 通量动画,并给它添加波纹。在这种情况下,波纹之所以移动,只是因为通量动画中的渐变在移动。 |

  magick flux_anim.gif -function Sinusoid 3.5,0 flux_rippled_anim.gif

[IM 输出]
你还可以在动画中让波纹本身动起来。不过,波纹本身可能需要使用大得多的“相位循环速率”(即“j = 5 * i”这个表达式)。另外,由于我们是在循环中再生成一个循环,因此需要生成更长的动画(本例中为 60 帧)。这样做的好处是,也会减慢较大“通量”的运动。 |

  for i in `seq 0 10 359`; do
    j=`expr $i \* 5`
    magick random.png -channel G \
            -function Sinusoid 1,${i} \
            -virtual-pixel tile -blur 0x8 -auto-level \
            -function Sinusoid 2.5,${j} \
            -separate +channel miff:-
  done |
    magick miff:- -set delay 15 -loop 0 ripples_flux_anim.gif

[IM 输出]
请注意第二张图中的波纹如何先从一个点涌出,然后又开始回到同一点。不过,它们并不是简单地反向运动。更好的多周期通量循环生成器,应该可以通过去除底层通量动画中的“负片”效应来消除这种轻微的怪异感。
FUTURE:使用波纹随机图像进行色散映射畸变。


平铺画布

平铺图像可以非常大或非常小,并且在水平和垂直相邻放置时可以覆盖较大的空间。感谢万维网,可用的平铺图像出现了爆炸式增长(找到你想要的图像是另一回事)。下面是从 Anthony 的图标库 复制的一系列平铺图像,供这些示例页面使用。 [IM 输出]
bg.gif | [IM 输出]
tile_aqua.jpg | [IM 输出]
tile_water.jpg | [IM 输出]
rings.jpg | [IM 输出]
tile_disks.jpg | [IM 输出]
tile_weave.gif
---|---|---|---|---|---
目前有很多方法可以在大面积上平铺图像。你可以对任何图像使用“[-tile](https://imagemagick.org/command-line-options/#tile)”,以完全替换原始背景图像(使用“Copy”合成运算符)。(更多详情请参见 平铺块合成。) |

  magick composite -tile tile_weave.gif -size 60x60  xc:none   tile_copy.gif

[IM 输出]
另一种方法是使用“tile:”编码器加载平铺图像并将其平铺为特定尺寸。 |

  magick -size 60x60 tile:bg.gif  tile_size.gif

[IM 输出]
| _请注意,“tile:”编码器会用当前背景颜色替换图像中的透明区域。这是因为它在内部生成所需大小的画布,并将图块图像“覆盖”到该画布上。

如果要保持透明度,请设置“-background none”或“-compose SRC”(详细信息请参见Src 合成方法)。_
---|---
你可以使用它生成比你需要的大得多的平铺图像,然后使用“[-composite](https://imagemagick.org/command-line-options/#composite)”将其覆盖在原始图像之上。如果平铺图像部分透明,则必须指定“[Over](compose.html#over)”的“[-compose](https://imagemagick.org/command-line-options/#compose)”方法。这是一种非常慢的平铺方法,尤其是对于大图像,并且还存在确定需要制作多大图像来进行叠加的问题。 |

  magick test.png -size 200x200 tile:tile_disks.jpg \
          -composite  tile_over.gif

[IM 输出]
通过将图块指定为“[-draw](https://imagemagick.org/command-line-options/#draw)”运算符的“图块填充图案”,你可以在另一个图像之上绘制图块图像,以创建你喜欢的任何形状或图形。这是因为“[-tile](https://imagemagick.org/command-line-options/#tile)”设置会覆盖绘制使用的任何“[-fill](https://imagemagick.org/command-line-options/#fill)”颜色设置。请参见 MVG 绘图设置。 |

  magick -size 60x60 xc: -tile tile_aqua.jpg \
          -draw "circle 30,30 2,30"   tile_draw.gif

[IM 输出]
这只适用于 "[-draw](https://imagemagick.org/command-line-options/#draw)" 以及像 "[-annotate](https://imagemagick.org/command-line-options/#annotate)" 这样同样利用 "[-draw](https://imagemagick.org/command-line-options/#draw)" 来执行功能的运算符。对于那些直接使用 "[-fill](https://imagemagick.org/command-line-options/#fill)" 颜色的图像运算符则不起作用,例如 "[label:](text.html#label)"、"[caption:](text.html#caption)" 和 "[text:](text.html#text)"。不过 "[-draw](https://imagemagick.org/command-line-options/#draw)" 内置了一些特殊的 颜色基元,比如把图像中的所有像素完全重置为填充颜色或平铺图案(如果已设置)。 |

  magick test.png   -tile tile_water.jpg  -draw "color 0,0 reset" \
          tile_reset.gif

[IM 输出]
这实际上与某些 纯色画布 方法使用 特定颜色 时采用的方法完全相同。只是这里我们使用 "[-tile](https://imagemagick.org/command-line-options/#tile)" 而不是 "[-fill](https://imagemagick.org/command-line-options/#fill)" 颜色。
更高级的方法是使用 扭曲运算符 配合特殊的 扭曲视口 设置,该设置被设为原始图像的尺寸(通过 已定义的全局构件百分号转义)。这基本上会把围绕小平铺图像的较小图块的 虚拟像素 映射出来,从而生成更大的平铺画布。 |

  magick rose: -set option:distort:viewport '%g' +delete  \
          tree.gif -virtual-pixel tile -filter point -distort SRT 0 \
          tile_distort_sized.gif

[IM 输出]
请参阅通过扭曲进行平铺(如下),了解平铺已存在于内存中的图像的相同技术。

偏移平铺画布

有时你需要对背景纹理的确切位置进行更多控制。要么将图块图案与其他图像对齐,要么避免与最终图像的其他部分产生不良相关性。对于许多标准平铺方法,可以使用“[-tile-offset](https://imagemagick.org/command-line-options/#tile-offset)”设置来实现。例如,这里我们分别使用“tile:”或“pattern:”来“滚动”平铺图像,用于直接创建平铺画布图像。

  magick -size 80x80 -tile-offset +30+30 tile:rose: offset_tile.gif
  magick -size 80x80 -tile-offset +20+20 \
                                 pattern:checkerboard offset_pattern.gif

[IM 输出] [IM 输出]

| 平铺偏移 设置在 IM 版本 6.3.9-9 之前是坏的。“X”偏移量会同时用于“X”和“Y”偏移值(给定的“Y”值会被忽略)。这意味着虽然上面的示例有效(X 和 Y 偏移量相同),但如果两个值不同,则可能不会产生预期结果。
---|---
这也适用于“magick montage”背景上的“[-texture](https://imagemagick.org/command-line-options/#texture)”设置。 |

  montage tree.gif     -geometry +24+24 \
          -tile-offset +30+30 -texture rose: offset_texture.gif

[IM 输出]
你还可以在“[-tile](https://imagemagick.org/command-line-options/#tile)”或“[-fill](https://imagemagick.org/command-line-options/#fill)”设置之前定义此设置。例如... |

  magick -tile-offset +30+30  -tile rose: \
          -size 80x80 xc: -draw 'color 30,20 reset'    offset_tile_fill.gif

[IM 输出]
请确保先重置 "[-size](https://imagemagick.org/command-line-options/#size)" 设置,再定义 "[-tile](https://imagemagick.org/command-line-options/#tile)" 图像,但这应在读取其他任何图像之后进行。 |

  magick -size 80x80  xc: \
          -tile-offset +20+20 +size -tile pattern:checkerboard \
          -draw 'color 30,20 reset'  offset_pattern_good.gif

[IM 输出]
无论如何,平铺偏移和平铺图像最好在第一次使用之前定义。这将得到与上述解决方案相同的结果。

图像已在内存中的平铺

平铺内存中的图像(创建或修改)并不容易,只有少数间接方法可用。

克隆并连接平铺图像

如果你不关心平铺图像的确切大小,则可以简单地将图像连接多次。例如,这里我们将图像平铺在 3x3 数组中。 |

  magick tree.gif \
          \( +clone +clone \) +append \
          \( +clone +clone \) -append \
          tile_clone.gif

[IM 输出]
这种平铺方法的优点是允许你翻转平铺图像。 |

  magick tree.gif \
          \( +clone -flop +clone \) +append \
          \( +clone -flip +clone \) -append \
          tile_clone_flip.gif

[IM 输出]
一般来说,只有当你了解要平铺的图像的尺寸时,此方法才实用。此外,克隆实际上非常快速且高效,因此这是一种相当简单且快速的平铺方法。特别是当你使用结果来进一步平铺更大的图像时。

使用 MPR 进行平铺:(内存程序寄存器)

更好的方法是以特殊的“内存中”文件格式“[mpr:](files.html#mpr)”(称为“内存程序寄存器”)保存图像。在此寄存器中,你可以使用“[-tile](https://imagemagick.org/command-line-options/#tile)”设置或使用特殊的“tile:”图像文件读取器。两者都只能从“保存的”图像文件格式进行配置。 例如,要使用“tile:”创建特定尺寸的平铺图像... |

  magick tree.gif   -write mpr:tile +delete \
          -size 100x100 tile:mpr:tile    tile_mpr.gif

[IM 输出]
| 请记住,“tile:”编码器会用当前背景颜色替换图像中的透明区域。(见上文)
---|---
或者,通过设置填充图案“[-tile](https://imagemagick.org/command-line-options/#tile)”或“[-fill](https://imagemagick.org/command-line-options/#fill)”并使用“[-draw](https://imagemagick.org/command-line-options/#draw)”重置颜色来平铺现有图像(请参阅颜色填充基元)... |

  magick tree.gif  -write mpr:tile +delete \
          granite: -fill mpr:tile  -draw 'color 0,0 reset' \
          tile_mpr_reset.gif

[IM 输出]
| 如果你要平铺包含透明度的图像,请使用“-alpha set”以确保目标图像也具有透明度。否则,生成的图像将显示图块的“隐藏”透明颜色。
---|---
或者,使用填充图案与其他绘制基元(例如圆形)一起绘制。 |

  magick tree.gif -write mpr:tile +delete \
          granite:  -tile mpr:tile  -draw 'circle 64,64 10,50' \
          tile_mpr_fill.gif

[IM 输出]
[mpr:](files.html#mpr)”后面的名称并不重要。这只是用于存储图像(在内存中)的“mpr”寄存器名称的标签。它可以是标签、数字、颜色,甚至是文件名。

通过扭曲使用虚拟像素进行平铺

在这种方法中,我们使用 虚拟像素设置 来生成大型平铺画布。该设置定义了实际图像周围区域(正常图像边界之外)应当如何呈现。提取虚拟像素最简单的方法,是使用 扭曲运算符 并配合特殊的 扭曲视口 设置。 |

  magick tree.gif -set option:distort:viewport 100x100+0+0 \
          -virtual-pixel tile -filter point  -distort SRT 0 \
          tile_distort.gif

[IM 输出]
你还可以访问其他样式的虚拟像素图块设置,例如“[Mirror](misc.html#mirror)”甚至“[CheckerTile](misc.html#checker_tile)”,以及使用视口设置的良好偏移图块控制。 |

  magick tree.gif -set option:distort:viewport 100x100-10-10 \
          -background firebrick  -virtual-pixel CheckerTile \
          -distort SRT 0 +repage    tile_distort_checks.gif

[IM 输出]
以这种方式使用 广义畸变运算符,还有一个额外好处:可以用一些非常复杂的方式扭曲平铺后的图像。相关示例可参见 扭曲仿射平铺。作为一个更复杂的例子,这里我使用 弧形扭曲,围绕位于视口中心的原点来平铺树图像。'45' 指定树的宽度覆盖的角度,而 '50' 定义树图块顶部边缘的半径。其余部分由此自然得到。 |

  magick tree.gif -set option:distort:viewport 100x100-50-50 \
          -virtual-pixel tile  -distort Arc '45 0 50' +repage \
          tile_distort_polar.gif

[IM 输出]

修改内置 IM 图案/平铺块

请参阅 ImageMagick 内置图像和图案 中的完整列表。这样的模式有很多,但我们在这里只看一两个。现在,内置图案通常是非常非常小的图像,可以平铺以覆盖大面积。但它本身看起来很简单,而且没什么用处。例如,这是提供的更大、更有趣的模式之一...... |

  magick pattern:checkerboard  pattern_default.gif

[IM 输出]
图案图像通常平铺在较大的区域上,方法是在画布创建过程中设置“[-size](https://imagemagick.org/command-line-options/#size)”,或者将其设置为填充平铺(请参阅上面的平铺画布)。如果没有尺寸设置,则使用图案的默认平铺尺寸。在本例中,它是 30x30 像素。现在,你可能会注意到 IM 当前提供的所有图案都是纯黑白的,唯一的例外是上一个示例中使用的“checkerboard”图案。 这是我最喜欢的平铺块图案之一...... |

  magick -size 60x60 pattern:hexagons  pattern_hexagons.gif

[IM 输出]
如果你对这些颜色不满意,可以使用“[-opaque](https://imagemagick.org/command-line-options/#opaque)”图像运算符进行替换。 |

  magick -size 60x60 pattern:hexagons \
          -fill blue -opaque black   -fill skyblue -opaque white \
          pattern_colored.gif

[IM 输出]
如果要为“checkerboard”图案着色,最好首先使用“[-auto-level](https://imagemagick.org/command-line-options/#auto-level)”将两种灰色映射为黑色和白色,然后替换这两种颜色。这里,我们没有使用“[-opaque](https://imagemagick.org/command-line-options/#opaque)”来替换颜色,而是使用“[+level-colors](https://imagemagick.org/command-line-options/#level-colors)”运算符(IM在v6.2.4-1中添加)。这个用起来比较容易一点。 |

  magick -size 60x60 pattern:checkerboard -auto-level \
          +level-colors red,blue     pattern_color_checks.gif

[IM 输出]
你还可以使用“[-floodfill](https://imagemagick.org/command-line-options/#floodfill)”运算符为图案着色。然而,为了使其正常工作,必须在平铺修改后的图案之前完成此操作。在这种情况下,我还必须将平铺块延伸三倍,以便用我想要的常规颜色图案对它们进行着色。 |

  magick -size 30x54 pattern:hexagons \
          -fill tomato     -opaque white \
          -fill dodgerblue -draw 'color 10,10 floodfill' \
          -fill limegreen  -draw 'color 10,25 floodfill' \
          -roll +15+27 \
          -fill dodgerblue -draw 'color 10,10 floodfill' \
          -fill limegreen  -draw 'color 10,25 floodfill'   miff:- |\
    magick -size 100x100 tile:- pattern_color_hexagons.gif

[IM 输出]
上面,我们使用了两个命令管道将彩色图案的创建与其实际使用分开。如果你想通过一个命令完成此操作,请参阅上面的平铺内存中的图像。 你还可以扭曲和扭曲简单的平铺块图案以创建有趣的变化。例如,我发现六边形图案上的“皱纹”效果(借鉴自字体图像生成器中的皱纹IM效果的技术)特别有趣。 |

  magick -size 160x100 pattern:hexagons \
          -wave 3x100 -background white -rotate 90 -wave 4x66 -rotate -87 \
          -gravity center -crop 120x90+0+0 +repage   pattern_distorted.gif

[IM 输出]

修改平铺图像

人们在修改图块(无论是现有图块,还是某个内置图案)时面临的最大问题,是许多图像操作会破坏图像的“可平铺性”。例如,这里我采用了内置的“hexagon”图案,并尝试对其进行修改,以生成宽六边形线条的带阴影灰度图案。 |

  magick pattern:hexagons  -rotate 90 \
          -blur 0x1  -edge 1  -negate  -shade 120x45 \
          miff:- |\
    magick -size 100x100 tile:-   tile_mod_failure.jpg

[IM 输出]
第一个命令生成“平铺图像”,第二个命令实际将其平铺出来,以便你可以看到它们如何组合在一起。如你所见,生成的平铺图像并不能正确平铺,平铺后的图像中可以清楚看到人为的边缘失真。基本上,你已经失去了原始图块沿图像边缘的均匀性。一种解决方案是使用特殊的 虚拟像素 设置;在查找实际图像边界之外的颜色时,它会让运算符认为图像会绕回边缘。 |

  magick pattern:hexagons  -rotate 90  -virtual-pixel tile \
          -blur 0x1  -edge 1  -negate  -shade 120x45 \
          miff:- |\
     magick -size 100x100 tile:-   tile_mod_vpixels.jpg

[IM 输出]
这是结合两种相关平铺块图案并使用不同效果来创建不寻常的砖墙平铺块的另一个示例。 |

  magick pattern:leftshingle pattern:rightshingle +append \
          -virtual-pixel tile  -blur 0x0.75 -resize 150% -shade 100x45 \
          -fill Peru  -tint 100%   miff:- |\
    magick -size 100x100 tile:-   tile_slanted_bricks.jpg

[IM 输出]

替代方法

除了依赖 虚拟像素,还有另一种方法。基本上,我们在操作图像之前自己提供“虚拟边缘像素”,以避免可能出现的边缘影响。做法是先把图像平铺到稍大一点的区域上。修改图像后,我们可以重新提取图块,避开引入的边缘变形。根据所执行图像操作的范围,它不必大很多。我发现 15 到 40 个像素应当能阻止最终结果中的所有边缘影响。要重新提取图像,可以使用 "[-shave](https://imagemagick.org/command-line-options/#shave)" 削去额外像素,或者从处理后图像的中间用 "[-crop](https://imagemagick.org/command-line-options/#crop)" 裁出原始平铺块大小。例如,这里我创建一个 3D "[-shade](https://imagemagick.org/command-line-options/#shade)" 效果,使用的是内置的 'hexagons' 图案。 |

  magick -size 60x60 tile:pattern:hexagons  -rotate 90 \
          -blur 0x1  -edge 1  -negate  -shade 120x45 \
          -gravity center -crop 18x30+0+0 +repage miff:- |\
    magick -size 100x100 tile:-   tile_mod_success.jpg

[IM 输出]
请注意,你提取的图块的确切位置并不重要。只要远离扭曲的边缘并使用与原始平铺相同的尺寸,就可以在平铺图像中的任何位置裁剪可平铺图像。我们没有将图像平铺到更大的区域,而是使用“双克隆”技术将平铺覆盖的区域加倍。完成后,只需从图像中心裁剪出 50% 的部分并取回修改后的图块即可。这意味着你不需要知道正在使用的图块的确切尺寸。 |

  magick pattern:circles \( +clone \) +append \( +clone \) -append \
          -fill grey -opaque black  -blur 0x0.5 -shade 120x45 \
          -gravity center -crop 50%  +repage    miff:- |\
    magick -size 100x100 tile:-   tile_circles.jpg

[IM 输出]
生成平铺图像。生成可平铺的图像时面临的最大问题是匹配图像的边缘和角落,以便它们可以无缝组合。如果不这样做,你将得到的只是一组带有重复图像副本的方框。这并不容易,而且可能是一次非常令人沮丧和令人烦恼的经历。出现在平铺一侧边缘的对象必须重新出现在图像的另一侧,以便在平铺时重塑整个图像。虽然这对于计算机生成的图像来说相当容易做到,但创建具有真实世界照片的良好平铺图像几乎是不可能的。另一个大问题是尽量避免平铺块看起来重复。唯一真正的解决方案是使图块图像足够大以包含非常相似但仍然不同的元素,以便重复的图案不那么明显。这使得生成看起来不重复的小图块特别困难。

FUTURE: 关于生成平铺图案,有什么想法或建议吗?有人吗?

或者滚动,添加一个元素,滚动,添加一个元素,等等......

欢迎任何建议或示例。

关于从真实照片生成图块的建议,例如水、落叶、
云、灰泥、砖砌等重复图案......

生成埃舍尔风格的平铺块图案。

随机噪声图块

原始随机噪声画布一开始就没有边缘特征(每个像素颜色完全独立于任何相邻像素),因此可以平铺它而不必担心边缘失真。基本上,它在像素级别上是极其随机的,因此边缘一开始就不匹配,并且当你平铺它时不会丢失任何内容。不幸的是,很少有情况可以直接将原始随机噪声图像用于实际目的。它是非常随机且无用的。但是,通过修改图像同时保留其固有的可平铺性,你可以创建几乎任何你想要的随机平铺图案。 例如,让我们看一下原始图块,即基本的“[-blur](https://imagemagick.org/command-line-options/#blur)”,使用与上一个示例中使用的相同“修改图块”技术。 |

  magick -size 64x64 xc: +noise Random \
          -virtual-pixel tile -blur 0x6 -auto-level  tile_random.jpg

  magick -size 128x128   tile:tile_random.jpg   tiled_random.jpg

[IM 输出]
[IM 输出]
该技术允许你对原始随机噪声图像应用几乎任何变换。例如... |

  magick -size 64x64 xc: +noise Random \
          -virtual-pixel tile  -blur 0x6  -edge 1  -fx G \
          -shade 280x45  -auto-level  tile_random_pits.jpg

  magick -size 128x128 tile:tile_random_pits.jpg tiled_random_pits.jpg

[IM 输出]
[IM 输出]
正如你所看到的,使用原始随机噪声图像创建随机图块要容易得多,并且结果没有任何边缘失真。这个特定的图像变换发布在背景图像页面上,标题为“坑”。请参阅该页面了解许多其他随机图像转换及其外观示例。

六边形平铺

与按方形方式平铺不同,“随机噪声”图像可以用来生成非常不同类型的图块。通过将图像尺寸加倍,并把图块错开半个图块重新铺到额外空间中,就可以生成基本的随机噪声六边形图块图案。 这与平铺 ImageMagick 特殊内置图案“pattern:hexagons”时获得的平铺效果相同。 |

  magick pattern:hexagons  tile_hexagons.gif

  magick -size 64x64  pattern:hexagons  tiled_hexagons.gif

[IM 输出]
[IM 输出]
然而,要使该图块看起来“六边形”,它不能是规则的正方形,甚至不能是双正方形。最终平铺块尺寸应为矩形。这个矩形的精确比例实际上包含一个无理数。这不太适合使用像素阵列的图像工作。然而,一个好的实用比例是 4:3,它用于大多数计算机和数码相机图像。 在这里,我们将相同的“随机噪声”图像(2:3 比例的矩形)再叠加两次,以生成基本的六边形图案(4:3 的矩形)。然后使用背景图像页面中的“paint_3s”变换对六边形平铺的随机噪声图块进行变换,以生成看起来非常漂亮的六边形图块图案。 |

  magick -size 48x64 xc: +noise Random  -write mpr:rand \
          -extent 96x64  -page +48-32 mpr:rand  -page +48+32 mpr:rand \
          -flatten          tile_hex_random.jpg

  magick tile_hex_random.jpg -virtual-pixel tile -blur 0x10 -paint 3 \
          -shade 280x45 -auto-level  tile_hex_layered.jpg

  magick -size 160x160  tile:tile_hex_layered.jpg  tiled_hex_layered.jpg

[IM 输出]
[IM 输出]
如果你查看图块产生的图案,你会发现任何一个具体特征周围,都会有同一特征的 6 个副本围成一圈。这就是该图块产生的“六边形”图案,尽管它仍然像所有其他平铺图像一样按同一种“方形”图案平铺。上面“六边形图块”图案的一种变体,是将图块图像在垂直方向加倍,而不是像上面那样在水平方向加倍。结果是六边形图案旋转 90 度。不过,它仍然是同一种图案。 | _从数学上讲,上述做法并不是从现有图块生成新的 壁纸群。原始的“非六边形”图像和最终版本都属于同一个“p1”平铺群。

我们上面实际做的,是把菱形的“原型图块”平铺图案,转换成同一平铺图案中更大、矩形且正交对齐的“基本区域”。这样你就可以使用标准平铺方法来平铺图像。
---|---
_Future:翻转额外的图像以生成更大的平铺图案(pmg 平铺群)。
Future:如何从图像中剪切(遮罩)六边形,使其可以无缝且无重叠地完美平铺。

三重六边形平铺

就像我们给“hexagons”内置图案上色时所做的那样(参见上面的 修改内置 IM 图案/平铺块),你可以先制作初始图块的三种不同变体(例如旋转),然后重新映射它们以形成更大的图块。当然,就像我给“hexagons”图案上色时一样,最终的平铺图像需要放大三倍,以生成重复的矩形平铺图案。生成的三个图块之间的差异不能太大,并且应该能够经受任何后处理,否则你就无法获得该技术的好处。这意味着初始图块也必须相当大,才能保留其中存在的任何独特特征。例如,这里我们绘制一个非常简单的线条图,然后旋转它以产生 3 个相似变体。随后将这些旋转后的图像在更大的画布(大 6 倍)上平铺七次,以生成三重图像的六边形图案。 |

  magick -size 24x24 xc: -draw "rectangle 3,11 20,12" tile_line.gif

  magick tile_line.gif -gravity center \
    \( +clone -rotate    0 -crop 24x18+0+0 -write mpr:r1 +delete \) \
    \( +clone -rotate  120 -crop 24x18+0+0 -write mpr:r2 +delete \) \
              -rotate -120 -crop 24x18+0+0 -write mpr:r3 +repage \
              -extent 72x36 \( -page  +0+0 mpr:r3 \) \
    \( -page +24+0  mpr:r1 \) \( -page +48+0  mpr:r2 \) \
    \( -page -12+18 mpr:r1 \) \( -page +12+18 mpr:r2 \) \
    \( -page +36+18 mpr:r3 \) \( -page +60+18 mpr:r1 \) \
    -flatten tile_hex_lines.jpg

  magick -size 120x120  tile:tile_hex_lines.jpg  tiled_hex_lines.jpg

[IM 输出]
[IM 输出]
[IM 输出]
但是,上述方法仅适用于在原始图像中心平铺小形状的情况。它不适用于一般图像。对于一般的六边形平铺图像,还需要用蒙版剪出等边三角形。旋转该部件,使等边三角形的边呈镜像。这不是一件容易的事。

对角镜像平铺

这是一种将任何方形图像转换为围绕中心点的 8 个镜像的方法。具体来说,它会生成复杂的“p4m”平铺图案。首先,生成一个随机色调图像,并使用源图像的左下半部分对其进行对角镜像,然后水平和垂直镜像。 |

  magick -size 50x50 xc: +noise Random -virtual-pixel Tile -blur 0x5 \
          -auto-level -separate -background white \
          -compose ModulusAdd -flatten -channel R -combine +channel \
          -set colorspace HSB -colorspace RGB   tile_diag_source.jpg

  magick tile_diag_source.jpg     \( +clone -transpose \) \
          \( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
          -composite \
          \( +clone -flop -chop 1x0 \) +append \
          \( +clone -flip -chop 0x1 \) -append \
          tile_diag_mirror.jpg

[IM 输出]
[IM 输出]
对角镜像是先执行 转置,再使用通过 Voronoi,稀疏颜色 生成的掩模得到的。请注意,由于正方形的像素几何形状,这个对角镜像也会以同样方式在镜像线两侧自动共享一行像素。在创建垂直和水平的 上下翻转和左右翻转 之前,我还会沿边缘移除一组像素。我还建议在将此图像用作“图块”之前,删除顶部和左侧边缘上的另一行和一列像素。你不一定要这样做,但我认为这样看起来更好。如果不删除这一行和一列边缘像素,图像拼接处就会出现难看的双像素“接缝”。另一种方法是先平铺原始随机图像,然后执行 背景图案 转换;这样沿镜像线出现“被裁切的外观”的可能性较小,过渡也更平滑。 |

  magick -size 51x51 xc: +noise Random   \( +clone -transpose \) \
          \( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
          -composite \
          \( +clone -flop -chop 1x0 \) +append \
          \( +clone -flip -chop 0x1 \) -append \
          -chop 1x1 \
          \
          -virtual-pixel Tile -blur 0x5 -auto-level \
          -separate -background white \
          -compose ModulusAdd -flatten -channel R -combine +channel \
          -set colorspace HSB -colorspace RGB    tile_p4m.jpg

[IM 输出]
第一部分是“随机数据平铺”的生成,第二部分是将随机数据转换为“色调”映射。它还向初始图像添加额外的像素,随后对其进行适当裁剪以生成平铺图像。
有关平铺图像及其背后数学的更完整介绍,请参阅维基百科:壁纸群。上面探讨的只是你可以创建的众多平铺块图案中的一小部分。
p4g”与上面的“p4m”平铺几乎完全相同,但它不使用翻转,而是使用镜像正方形的 180 度旋转来生成完整的平铺图像。不过,由于这些图像不是通过镜像连接在一起的,边缘会变得分离且不连续,因此不能把现有图像用作平铺块源图像。但是,你可以先平铺原始随机数据,再处理生成的平铺图像,以产生平滑的结果。 |

  magick -size 50x50 xc: +noise Random   \( +clone -transpose \) \
          \( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
          -composite \
          \( +clone -rotate -90 \) +append \
          \( +clone -rotate 180 \) -append \
          \
          -virtual-pixel Tile -blur 0x5 -auto-level \
          -separate -background white \
          -compose ModulusAdd -flatten -channel R -combine +channel \
          -set colorspace HSB -colorspace RGB    tile_p4g.jpg

[IM 输出]
请注意,由于这种平铺具有非镜像平铺的性质,在连接之前不需要从边缘删除重复的像素行或列。不过,如果你想在两种情况下遵循同样的流程,删除它们也没有什么坏处。