ImageMagick 示例 --
高级技巧

索引
ImageMagick 示例前言和索引
   从形状创建 3D 项目符号    使用脚本生成大量图像
3D 灰度阴影图像的色彩着色和造型
制作 3D 标志 使用透明叠加层为基本形状图像着色
反射 添加多种类型的表面反射。
拼图碎片 从照片中剪切和增强奇形怪状的碎片
“凝胶”效果 调整高光的尺寸、亮度和锐度
使用“屏幕”和“叠印”合成进行亮度和暗化
“水族”效果 使用“曲线”调整高光。
可平铺的星星和彗星 随机点。
“我的天哪!全是星星!——2001太空漫游”
径向耀斑 围绕中心点生成随机光线和环。
此页面提供了一些非常大的示例,我们使用多种技术来产生一些复合图像处理效果,超越了 IM 的基本图像操作。主要技术在上面的索引中进行了总结。虽然许多技术在其他页面上提供了,例如创建字体模板、花哨的图像标签和使用蒙版,但这些页面展示了如何将这些技术组合在一起以产生更复杂的效果。

从形状创建 3D 项目符号 -- 基于脚本的方法

网络上有很多用于网页列表的“项目符号”图像。但是您可以生成自己的 3D 对象,并允许您使整个网站符合特定的风格,从而将所有内容联系在一起。最好的方法之一是创建一个“生成”脚本,让您可以自动生成一系列特定风格的按钮和形状,但可以使用您需要的任何颜色。这是一个非常简单的脚本。在这里,我们使用“-shade”选项从一个简单的形状透明度生成 3D 外观的对象。该形状仅具有直观的开/关透明度,并且得到仔细保留,使其可以作为通用网页上的透明 GIF 图像使用。然后使用“-tint”运算符对生成的灰度“阴影”图像进行着色,以设置图像的中调灰色,同时保持更极端的黑色和白色阴影不变。之后,将提供的图像的原始形状重新添加到着色的结果中。作为奖励,如果输入图像仅具有布尔透明度,则结果也具有适合 GIF 格式图像的布尔透明度。

    magick {input_image} -alpha set \
            \( +clone -channel A -separate +channel \
               -bordercolor black -border 5  -blur 0x2 -shade 120x30 \
               -normalize -blur 0x1 -fill {color} -tint 100 \) \
            -gravity center -compose Atop -composite \
            {output_image}
请注意,上述脚本仅读取一次输入图像。这允许您在使用“-”作为输入和输出文件名(可能还有 IM 图像格式设置)的命令管道中使用该脚本。这在编写您自己的 IM 脚本时可能很重要。以上命令被写入一个非常简单的 shell 脚本,名为“create_bullet”,并执行以下命令以生成一系列不同颜色的符号图像。

    magick +antialias -size 15x15 xc:none -draw 'circle 7,7 3,3'  ball.gif
    create_bullet ball.gif  grey    ball_grey.gif
    create_bullet ball.gif  red     ball_red.gif
    create_bullet ball.gif  green   ball_green.gif
    create_bullet ball.gif  blue    ball_blue.gif
    create_bullet ball.gif  yellow  ball_yellow.gif
    create_bullet ball.gif  maroon  ball_maroon.gif
    create_bullet ball.gif  cyan    ball_cyan.gif

    magick -size 12x12 xc:black   square.gif
    create_bullet square.gif  grey    square_grey.gif
    create_bullet square.gif  red     square_red.gif
    create_bullet square.gif  green   square_green.gif
    create_bullet square.gif  blue    square_blue.gif
    create_bullet square.gif  yellow  square_yellow.gif
    create_bullet square.gif  maroon  square_maroon.gif
    create_bullet square.gif  cyan    square_cyan.gif

    # retrieve asterix symbol from
    # Anthony's Web Images, Symbols
    create_bullet asterix.gif  grey    asterix_grey.gif
    create_bullet asterix.gif  red     asterix_red.gif
    create_bullet asterix.gif  green   asterix_green.gif
    create_bullet asterix.gif  blue    asterix_blue.gif
    create_bullet asterix.gif  yellow  asterix_yellow.gif
    create_bullet asterix.gif  maroon  asterix_maroon.gif
    create_bullet asterix.gif  cyan    asterix_cyan.gif

    # Use a heart symbol from "WebDings" font (22 point => 16x16 pixel image)
    magick -font WebDings -pointsize 22 -background none \
            label:Y -trim +repage    heart.png
    create_bullet heart.png  grey    heart_grey.png
    create_bullet heart.png  red     heart_red.png
    create_bullet heart.png  green   heart_green.png
    create_bullet heart.png  blue    heart_blue.png
    create_bullet heart.png  yellow  heart_yellow.png
    create_bullet heart.png  maroon  heart_maroon.png
    create_bullet heart.png  cyan    heart_cyan.png
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] ==> [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
在生成项目符号时,仅使用源图像的形状或透明度,因此可以使用任何形状。选择适合您网站的独特形状。另请注意,可以使用 GIF 或 PNG,无论是否具有定义形状的透明度。该命令没有区别。如果您使用的图像大于此处显示的图像,您可能还想在阴影操作之前增加应用的模糊量。否则,您可能会发现只有靠近图像边缘的区域会变圆。当然,如果进行了一些改进或有其他想法,请告诉我,以便我们与他人分享。

制作 3D 标志

在此示例中,我们有一个扁平的彩色标志,形状复杂,我们希望对其进行图像处理以使其具有独特的 3D 外观。为此,我们使用徽标生成高光和阴影,并将它们转换为透明度以叠加到原始图像上。它使用了所有示例页面中的许多不同技术来逐步实现此效果。此示例大量使用了由阴影运算符生成的图像和各种Alpha 合成方法。我建议您在继续之前熟悉这些图像运算符,或者在您希望更好地理解正在发生的事情时查找它们。
但是,在我们开始之前,我们需要一个简单的徽标来应用我们的技术,以及它的蒙版……让我们首先为徽标示例创建颜色背景的形状……

  magick -size 170x100 xc:black \
          -fill white -draw 'circle    50,50  13,50' \
                      -draw 'circle   120,50 157,50' \
                      -draw 'rectangle 50,13 120,87' \
          -fill black -draw 'circle    50,50  25,50' \
                      -draw 'circle   120,50 145,50' \
                      -draw 'rectangle 50,25 120,75' \
          -fill white -draw 'circle    60,50  40,50' \
                      -draw 'circle   110,50 130,50' \
                      -draw 'rectangle 60,30 110,70' \
          -gaussian 1x1 -alpha off logo_mask.png
[IM Output]
现在,我们使用蒙版剪切徽标的纯色,并添加一些文本以生成一个简单的纯色徽标。

  magick logo_mask.png -background red -alpha shape \
          -font Candice  -pointsize 36  -fill white  -stroke black \
          -gravity Center  -annotate 0 "Ant" \
          logo.png
[IM Output]

现在,让我们使用叠加高光技术使其具有 3D 外观。

  magick logo.png  -alpha extract -blur 0x6  -shade 110x30  -normalize \
          logo.png  -compose Overlay -composite \
          logo.png  -alpha on  -compose Dst_In  -composite \
          logo_3D.png
[IM Output]
由于 IM 提供的新阴影生成运算符,添加阴影也更容易。

  magick logo_3D.png \( +clone -background navy -shadow 80x4+6+6 \) +swap \
          -background none  -layers merge +repage logo_3D_shadowed.png
[IM Output]
只是为了好玩,让我们最后将徽标叠加在类似“粗糙纸张”的背景上。还可以创建大量其他背景画布,请参阅背景示例以获取此类示例的集合。


magick logo_3D_shadowed.png \ \( +clone +repage -alpha off -fx 'rand()' -shade 120x30 \ -fill grey70 -colorize 60 \ -fill lavender -tint 100 \) \ +swap -composite logo_3D_bg.jpg
[IM Output]

反射

反射相对容易实现,但通常看起来并非如此。您必须处理诸如表面颜色和纹理等方面,以及这种效果如何随着表面反射与被该表面反射的对象之间的距离而增加。基本上,本来应该是一个相对简单的事情,很快就变得非常复杂了。[IM 输出]因此,让我们从一个相对简单的图像的反射开始,在本例中是皮卡丘角色 Azumarill 的图像(见右)。如果您愿意,可以替换您自己的图像。现在,要进行完美的镜面反射,您只需复制并翻转源对象,并在其后面添加一些背景以使其具有一定的上下文。例如……

  magick pokemon.gif \( +clone -flip \) -append \
          -size 100x100 xc:black +swap \
          -gravity North -geometry +0+5 -composite  reflect_perfect.png
[IM Output]

表面颜色 - 一般衰减

需要注意的是,上述反射是完美的,实际上并不像黑色表面上的反射。它更像是原始图像的“镜面瓷砖”,这也是事实。即使是普通的浴室镜子也不会反射所有照射到它上面的光,而且它是您可以获得的最好的镜子。因此,反射的第一条规则是……
反射永远不完美。
所有反射都不是 100% 的反射,因此会受到表面(或周围环境)颜色的影响。这是一个不完美的世界,反射很好地增强和展现了这些不完美之处。因此,让我们再试一次,但这次让我们用反射表面的颜色为反射着色。您可以通过两种方式执行此操作。最简单的方法是简单地着色反射与表面相同的颜色。着色量取决于表面反射的程度,对于彩色表面,通常效果很差,因此需要添加大量的颜色,“65%”对于黑色表面来说非常不错。

  magick pokemon.gif \
      \( +clone -flip -fill black -colorize 65% \) -append \
      -size 100x100 xc:black +swap \
      -gravity North -geometry +0+5 -composite  reflect_colored.png
[IM Output]
好多了……现在它看起来确实像一个反射!使反射变弱的另一种方法是使反射图像半透明或半透明。例如,将图像的 alpha 值相乘,以使仅大约 35% 的源对象可见。

  magick pokemon.gif -alpha on \
      \( +clone -flip -channel A -evaluate multiply .35 +channel \) -append \
      -size 100x100 xc:black +swap \
      -gravity North -geometry +0+5 -composite  reflect_alpha.png
[IM Output]
这实际上是首选,因为它意味着表面的颜色可以是任何颜色,甚至可以是某种类型的颜色纹理或图案。例如,让我们使用查看远方地平线中的无限平铺技术生成一个水平木地板。

  magick tile_wood.gif   -set option:distort:viewport 100x100 \
          -virtual-pixel tile     -distort Perspective \
                '0,0 -20,65  96,0 60,40  96,96 120,55  0,96 50,99' \
          wooden_floor.png
[IM Output]
现在,将我们的图像与其半透明反射叠加到这个木地板上。

  magick pokemon.gif -alpha on \
      \( +clone -flip -channel A -evaluate multiply .35 +channel \) -append \
      wooden_floor.png +swap \
      -gravity North -geometry +0+5 -composite  reflect_wood.png
[IM Output]
如果没有反射对象,木质表面看起来相当沉闷和毫无生气,但如果反射了一些物体,地板突然显得非常抛光!

失真源

好的。让我们尝试一些更花哨的东西,并为图像添加一些 3D透视深度。

  magick pokemon.gif -alpha on   -virtual-pixel transparent \
      +distort Perspective '0,0 0,0  0,64 0,64  64,0 54,10  64,64 54,54' \
      \( +clone -flip -channel A -evaluate multiply .35 +channel \) -append \
      +filter  -size 100x100 xc:black +swap \
      -gravity North -geometry +0+5 -composite  reflect_distort_bad.png
[IM Output]
这显然是错误的。它看起来像是图像被扭曲了,但仍然平放在原始用户面前。为什么呢,因为……
与表面接触的物体也将与它们的反射接触。
这看起来很明显,但我见过有人弄错了。当然,如果物体漂浮在表面上方,则它们将不会接触。解决此问题的一种方法是分别扭曲源图像及其反射,然后图层合并结果。

  magick pokemon.gif -alpha on   -virtual-pixel transparent \
      \( -clone 0 \
         +distort Perspective '0,0,0,0  0,64,0,64  64,0,54,10  64,64,54,54' \) \
      \( -clone 0  -channel A -evaluate multiply .35 +channel \
         +distort Perspective '0,0,0,128  0,64,0,64  64,0,54,98  64,64,54,54' \
      \) -delete 0 +swap -background none  -layers merge \
      +filter  -size 100x100 xc:black +swap \
      -gravity North -geometry +0+5 -composite  reflect_distort_sep.png
[IM Output]
正如您从非常不同的扭曲参数集中看到的那样,扭曲反射可能会变得非常困难。由于对第一个扭曲的简单更改需要对反射图像的第二个扭曲进行计算更改,因此它变得更加困难。还有两条规则可以告诉您如何计算反射扭曲的坐标。
水平表面的反射总是直接向下。
也就是说,反射总是朝向用户,作为用户,直接位于图像的前面,这意味着水平表面上的任何反射都将向下,直接朝向用户。这是物理定律,如果您希望您的图像至少是半现实的,那么您不希望打破它。最后,您应该记住的另一条规则。
垂直表面在水平表面上的反射具有
与反射对象高度相同的反射
无论对象在图像中看起来有多“遥远”,其在最终图像中的反射高度都应与被反射的对象高度相同!这并不明显,而且很容易出错。

这三条规则意味着,反射坐标的 X 值保持不变,但 Y 值围绕“表面接触点”向下翻转与其高于该点的量相同。

因此,通过一定的谨慎,您可以根据扭曲源图像的坐标计算反射的扭曲坐标。现在,这些规则还为我们提供了一种可以简化扭曲图像反射的方法。只需先将反射附加到源图像,然后像没有附加反射一样扭曲源图像,让其反射与主图像一起扭曲……

  magick pokemon.gif -alpha on   -virtual-pixel transparent \
      \( +clone -flip -channel A -evaluate multiply .35 +channel \) -append \
      +distort Perspective '0,0,0,0  0,64,0,64  64,0,54,10  64,64,54,54' \
      -gravity North  -crop 100x100+0-5\! \
      -background black -compose Over -flatten    reflect_distort.png
[IM Output]
正如您所看到的,这工作起来容易得多,并且您只需要处理一组对象的扭曲,从而使更改也变得更加简单。它还允许您使用其他无法重复的扭曲来创建单独的反射。例如,从图像生成 3D 弧线……


  magick pokemon.gif -alpha on   -virtual-pixel transparent \
      \( +clone -flip -channel A -evaluate multiply .35 +channel \) -append \
      +distort Barrel '0,0,0,1  0,0,-.35,1.5  32,32' \
      -gravity North  -crop 100x100+0-5\! \
      -background black -compose Over -flatten    reflect_3Darc.png
[IM Output]
在进入下一节之前,最后一点… 阴影通常遵循与反射相同的规则,除了最后两条规则。它们可能不会直接向下投射,而是指向远离光源的方向(对于远处的光源则平行)。此外,它们与“表面接触点”的距离也不会相同,但它们将具有相同的距离比率,只是不像反射那样为 1:1 比例。

渐变衰减

到目前为止,我们处理的是一个完全光滑的反射表面,但大多数表面都没有抛光到镜面般的光泽。看似光滑的表面在较小的尺度上实际上并不光滑,这反过来会影响从这样的表面反射的光。这种效应也随着反射光在物体和反射点之间传播的距离而增强。因此…
反射会变得更弱,更扭曲,
它离源图像越远。
创建距离效果的最简单方法是使反射离表面越远越弱。为此,通常可以使靠近图像的反射稍微明亮一些。

  magick pokemon.gif -alpha on \
      \( +clone -flip \
         -size 64x28 gradient:gray40-black   \
         -alpha off -compose CopyOpacity -composite \
      \) -append \
      -gravity North  -crop 100x100+0-5\! \
      -background black -compose Over -flatten    reflect_attenuated.png
[IM Output]
这效果相当不错,而且生成起来非常容易,因此它是一种相当常见的反射生成方法。该技术有效的原因是,很大一部分被反射的光不是完美的反射,而是更多地来自全局环境。你离原始图像越远,反射的原始图像就越少。

模糊衰减

构成源对象真实反射的组件,不会随着距离的增加而简单地变弱。实际上,随着距离的增加,反射会变得更模糊、更模糊和更扭曲,因为反射表面通常不是很光滑。这不是宏观扭曲,而是在非常小的微观层面上发生的扭曲。产生镜面反射效果的相同效应。也就是说,靠近反射源时,它们可以相当清晰,但离源越远,图像就变得越模糊。在 IM 6.5.5-0 版本之前,这很难实现(虽然可能,但需要很多技巧)。但是现在您可以使用 可变模糊映射 轻松地根据反射离源图像的距离来模糊反射。但是,为了使此方法有效,最好在对象周围添加一个透明的边框以进行模糊。在这些示例中,我扩展了最终图像,以便您可以看到整个反射,从而可以欣赏其效果。

  magick pokemon.gif -alpha on \
      -background None -gravity South -extent 100x100 \
      \( +clone -flip -channel A -evaluate multiply .35 +channel \
         -size 100x100 gradient:gray5-white \
         -compose Blur -set option:compose:args 10 -composite -compose Over \
      \) -append -trim +repage \
      -gravity North  -crop 100x140+0-5\! \
      -background black -compose Over -flatten    reflect_blurred.png
[IM Output]
可以通过使用垂直拉伸的模糊椭圆进一步增强反射模糊。例如,使用“10x30”的椭圆模糊参数,而不是“20”的简单圆形模糊。如果你将“模糊衰减”与“渐变衰减”结合起来,你将开始获得典型的不那么抛光但光滑的表面反射的非常逼真的反射。

  magick pokemon.gif -alpha on \
      -background None -gravity South -extent 100x100 \
      \( +clone -flip \
         \( -size 100x64 gradient:'rgba(0,0,0,0.6)-none' \
            -size 100x36 xc:none  -append \
         \) -compose Dst_In -composite \
         \( -size 100x100 gradient:gray5-white \
         \) -compose Blur -set option:compose:args 4x8 -composite \
      \) -append -trim +repage \
      -gravity North  -crop 100x140+0-5\! \
      -background black -compose Over -flatten    reflect_blur_atten.png
[IM Output]
对于平面,你很难获得比这更好的反射图像。
Future: To add examples of...
  Surface Texture effects
    frosted - or non smooth surfaces (small scale randomised distortions)
    rippled - water reflections
        (very little blur or attenuation, just stronger macro distortion)

拼图碎片

我被要求帮助处理的最有趣的事情之一是从更大的图片中剪裁并增强一个奇形怪状的“拼图”碎片。实际上,Theo van Hoesel,也称为“Mr Jigsaw”,想要生成很多不同的碎片,并以许多不同的旋转角度。以下是根据我们针对一个碎片的讨论而开发的,但使用正确的模板集,可以生成任何图案的碎片。
右侧是一个缩略图,链接到柏林德国大屠杀纪念馆照片的 800x600 图像。这是我在 2006 年 4 月欧洲旅行期间拍摄的照片。它看起来像是一个可以从中制作非常难的拼图的绝佳图像。在其下方是将从上图中提取的拼图碎片的模板图像。它是此类图像集的一部分。完整的拼图碎片集包含 192 个这样的蒙版,以 16x12 的阵列排列,包括边缘和角点。此特定拼图碎片是一个100x100 像素的蒙版,设计用于在800x600 像素的图像上使用+365+96 偏移量。这些数字只有在您有一组可以拼合在一起的不同碎片时才重要。如果您不打算这样做,那么当然可以使用任何您喜欢的偏移量。   [photo]
[IM Output]
我本人已经收集了许多这样的拼图集,可以让我制作任何图像的拼图。而这正是 Theo van Hoesel 在他的网站上实际做的事情。如果您正在制作一个真实的拼图,那么偏移信息非常重要,因为它标识了该碎片在原始图像中的位置和放置。因此,我将尝试保留此信息。请注意,由于形状周围的额外填充,蒙版的偏移量在某些情况下可能是负数,因此您可能需要测试和调整图像命令以处理这种情况。额外的填充本身将允许您轻松地旋转、添加厚度和阴影效果到最终图像,而无需更改剪裁拼图碎片的大小或偏移量。
但是,首先让我们将此模板转换为轮廓。

    magick jigsaw_tmpl.png -edge .5 -blur 0x.5 jigsaw_edge.png
[IM Output]
然后,我可以将其叠加到图像上,以大致了解将要剪裁以形成拼图碎片的内容。

    magick holocaust_md.jpg \
            \( jigsaw_edge.png -negate \) -geometry +365+96 \
            -compose multiply -composite \
            -crop 100x100+365+96 +repage jigsaw_outline.png
[IM Output]
通常在生成拼图时不会这样做,但在碎片的位置不重要(因为它不是更大拼图的一部分)时这样做很有用。如果是这样,您可以调整偏移量以选择该拼图碎片的更好内容。
由于“-edge”的工作方式,上面生成的拼图轮廓位于蒙版(白色)区域蒙版图像内部。如果您以后想利用此轮廓,这一点可能很重要。
好的,我们有一个拼图形状,以及要剪裁的碎片的偏移量。所以让我们剪裁它并旋转它。

    magick holocaust_md.jpg \
            -crop 100x100+365+96\! -background none -flatten +repage \
            \( jigsaw_tmpl.png -alpha off \) -compose CopyOpacity -composite \
            -rotate -20 -gravity center -crop 100x100+0+0 +repage \
            jigsaw_cutout.png
[IM Output]
请注意,我们将源图像裁剪到模板形状覆盖的区域。我们不需要蒙版外部的区域,并且尽早将其移除将加快图像处理速度。另请注意 视口裁剪 的特殊用法,后跟“-flatten”。这种裁剪方法将确保我们能够保证一个 100x100 像素的图像,从中“剪裁”模板,即使使用边缘或角点碎片的蒙版,并且还可以处理图像顶部或左侧边缘上或附近的碎片的负偏移量。旋转也在此时执行,因为大多数增强功能都会根据特定方向添加效果。该旋转的结果也进行了中心裁剪,因为此运算符通常会扩展结果图像的大小,具体取决于所使用的旋转角度,而我们不希望它这样做。第一个增强功能是在边缘周围为碎片提供略微斜面或圆形的突出显示。这与阴影突出显示叠加相同,它允许对突出显示的生成方式进行精细控制(4 个单独的因素)。

   magick jigsaw_cutout.png \
           \( +clone -channel A -separate +channel -negate \
              -background black -virtual-pixel background \
              -blur 0x2 -shade 120x21.78 -contrast-stretch 0% \
              +sigmoidal-contrast 7x50%  -fill grey50 -colorize 10% \
              +clone +swap -compose overlay -composite \) \
          -compose In -composite jigsaw_bevel.png
[IM Output]
在真实的拼图中,这种斜面是机器压切拼图碎片的结果。它还会使碎片略微凹陷,因此如果将碎片拼合在一起,您仍然可以看到切口的印记。现在让我们为碎片添加一些厚度。这是我找到的最好最快的方法,尽管我认为它不是一个非常好的技术。如果您能找到更好的方法,请告诉我。

   magick jigsaw_bevel.png \
           \( +clone -fill DarkSlateGrey -colorize 100% -repage +0+1 \) \
           \( +clone -repage +1+2 \)  \( +clone -repage +1+3 \) \
           \( +clone -repage +2+4 \)  \( +clone -repage +2+5 \) \
          -background none -compose DstOver -flatten \
          jigsaw_thickness.png
[IM Output]
最后,如何添加一些阴影?

    magick jigsaw_thickness.png \
            \( +clone   -background Black -shadow 50x3+4+4 \) \
            -background none -compose DstOver -flatten \
            jigsaw_shadow.png
[IM Output]
以上所有命令都可以轻松地保存到单个 shell 脚本中,我已经为自己的使用做了这件事。脚本“jigsaw”将采用三个图像参数:源照片、模板和目标,以及启用上面显示的各种增强功能的众多选项。它也不需要使用拼图形状。任何蒙版模板都可以用于剪裁图像的一部分,并添加适当的效果。上述内容与我的脚本版本之间最大的区别在于,默认情况下,脚本使最终图像尽可能小,同时跟踪剪裁图像的偏移量。通过保留此偏移位置,您可以使用简单的“-mosaic”或“-flatten”将多个碎片叠加在一起以产生有趣的效果(请参见下面的最后一个示例)。以下是一些使用此脚本的不同方法的示例。

    jigsaw -o +365+96 -m  null: jigsaw_tmpl.png  jigsaw_mask.png
    magick -size 800x600 xc:gray miff:- |\
                 jigsaw -r 30 -l -h -s miff:- jigsaw_mask.png jigsaw_grey.png
    jigsaw -r -60 -h -t 4 -s holocaust_md.jpg jigsaw_mask.png jigsaw_piece.png

    magick jigsaw_cnr.png -resize 50% -flip -flop -repage 120x90 \
            -background black -flatten -flip -flop jigsaw_cnr_tmpl.png
    jigsaw -t 3 -s  -r 15  -d +15+7 \
            holocaust_tn.gif jigsaw_cnr_tmpl.png   holocaust_piece_tn.png
    magick jigsaw_cnr_tmpl.png -negate png:- |\
      jigsaw -t 3 -s holocaust_tn.gif png:-   holocaust_puzzle_tn.png
    magick holocaust_puzzle_tn.png  holocaust_piece_tn.png \
            -background none  -mosaic    holocaust_jigsaw_tn.png
[IM Output] ==> [IM Output] [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output] [IM Output] ==> [IM Output]
最后一张图像是可能的拼图缩略图样式的开始… 它采用一个角形拼图碎片,并通过一些缩放和扩展将蒙版转换为全尺寸图像模板蒙版。然后,它不仅用于从现有的缩略图中剪裁角碎片,还用于否定以生成图像的其余部分。然后,叠加这两张图像会产生一个非常漂亮的拼图缩略图。请注意选项中“-d +15+7”的使用。这将生成 PNG 图像的“页面偏移量”相对于其在图像中的原始位置偏移少量,从而简单轻松地产生所示结果。有关其他可用选项,请参见脚本本身。
由于生成的页面偏移量可能是负数,并且可能包含可选的柔和阴影效果,因此建议仅对提取的碎片使用 PNG 图像。GIF 图像无法处理负页面偏移量或阴影效果,并且在涉及透明度时也不会产生平滑的抗锯齿边缘。

通常,您应该避免使用 GIF(和 JPEG)图像,除非是最终图像。有关更多信息,请参见常见图像格式示例页面。
您不仅限于拼图模板,任何形状的蒙版都可以与任何图像一起使用。请告诉我你发现了什么。我还没有完成“jigsaw”脚本的开发,因为我想对突出显示、厚度和阴影效果进行一些更好的控制,并可能添加一个“否定蒙版”选项。但是,它基本上是一个完整的可供您使用的程序。如果您将其用于网页,请给我一个链接 :-) 对于那些具有某些 PerlMagick API 技能的人,请尝试获取上述脚本并将其转换为 PerlMagick 以提高速度,然后将其提交给我,以便其他人也可以使用它,并了解您在使用 IM 方面有多么出色。始终欢迎提出进一步的建议和想法。
如果您只想使用一组蒙版(有或没有虚拟像素偏移量)从图像中剪裁所有碎片,那么以下命令将让您非常快速地完成所有操作。

  magick mask_*.png -set filename:mask %t -alpha shape \
          null: image.jpg -compose In -layers composite \
          pieces_%[filename:mask].png
其他每个生成的“pieces_mask_*.png”图像不仅包含原始图像中具有正确偏移量的相应图像,而且还在最终图像中保留了该偏移量。它使用 多层合成 将特殊“null:”标记图像左侧的所有图像与右侧的单个图像合并来实现此目的。作为额外奖励,它会将所用蒙版的文件名合并到碎片图像文件名中(包括其最终图像文件格式),从而更容易识别哪个碎片是什么。(有关详细信息,请参见文件名百分比转义。请注意,蒙版不必完全覆盖整个原始图像,但也不应在碎片之间留下空格或间隙。当然,对于正确的拼图,所有蒙版都应对齐,以便产生无缝的整体,如Dst_Out 合成示例中所示。

“凝胶”效果

上面使用的 3D 阴影只是您可以使用高光和阴影效果实现的开端。通过对“-shade”的输出进行各种直方图调整,可以获得大量的可能性。您可以重现的一种效果称为“凝胶”效果,例如在“Photoshop”的教程网站上经常看到(在 Google 上搜索“凝胶效果教程”)。首先,让我们创建所需的形状。这可以是预先准备好的图像,也可以从“Dings”字体中提取,就像我们上面对 3D 子弹形状的“心”所做的那样。在这种情况下,让我们使用一个简单的椭圆形作为按钮……

  magick -size 100x60 xc:none \
          -fill red -draw 'circle    25,30  10,30' \
                    -draw 'circle    75,30  90,30' \
                    -draw 'rectangle 25,15  75,45' \
          gel_shape.png
[IM Output]
现在,让我们使用高度修改的模糊阴影操作,为彩色形状添加清晰的“凝胶”高光……

    magick gel_shape.png \
            \( +clone -alpha extract  -blur 0x12  -shade 110x0 -normalize \
               -sigmoidal-contrast 16,60% -evaluate multiply .5 \
               -roll +5+10 +clone -compose Screen -composite \) \
            -compose In  -composite  gel_highlight.png
[IM Output]
我们在模糊透明度(蒙版)通道的副本后应用了“-shade”以将其圆角化。此阴影使用了没有任何“高度”或“方位角”的光源,这基本上意味着我们得到一个仅在模糊形状一侧的灰色高光,以及其他所有内容的黑色。然后使用“-sigmoidal-contrast”运算符调整(锐化)此高光灰度级,以减小高光区域的大小(“60%”阈值级别)并锐化其边缘(使用非常高的“16”指数因子)。使用如此高的指数值,运算符几乎就像一个“模糊”的“-threshold”运算符,用于根据原始图像的形状生成一个平坦的彩色区域。有关此平滑对比度/阈值函数的更多信息,请参阅 S 形非线性对比度。最后,使用“-evaluate”调整高光的级别,将所有颜色乘以所需的高光级别,然后使用“-roll”将其位置移到形状区域。现在,由于高光在黑色上是灰色的(黑色保持不变),因此使用“屏幕” alpha 合成来通过给定的灰色级别来提亮非黑色区域。现在剩下的就是稍微使边界变暗……

    magick gel_highlight.png \
          \( +clone -alpha extract  -blur 0x2 -shade 0x90 -normalize \
             -blur 0x2  +level 60,100%  -alpha On \) \
          -compose Multiply  -composite  gel_border.png
[IM Output]
请注意,这次我使用了垂直照明的“-shade”来使边缘变暗,这使得我想保留的区域保持不变,为白色。因此,在使用 反向级别调整调整灰度级并恢复 Alpha 提取方法保存的透明度后,我能够使用“乘法” alpha 合成使受影响的边界变暗。让我们用一些文字和阴影效果完成椭圆形“凝胶”按钮……

    magick gel_border.png \
            -font Candice  -pointsize 24  -fill white  -stroke black \
            -gravity Center  -annotate 0 "Gel"  -trim -repage 0x0+4+4 \
            \( +clone -background navy -shadow 80x4+4+4 \) +swap \
            -background none  -flatten    gel_button.png
[IM Output]

“水”或“气泡”效果

您还可以调整完整的 3D“-shade”(带 30 度照明)色调以产生“水”效果。但是,为此,我们需要以类似于使用“Gimp”和“Photoshop”等 GUI 图形程序的方式进行直方图调整。我将首先逐步缓慢地执行此操作,以便您可以看到我正在执行的步骤。首先,让我们创建一个要使用的图像,在这种情况下,它是一个弯曲的字母 A。

  magick -background none -fill DodgerBlue \
          -font Candice -pointsize 72  label:A  -trim +repage \
          -bordercolor None -border 1x1 \
          aqua_shape.png
[IM Output]
请注意,我在图像周围添加了一个像素的透明边框。这使得后续的处理步骤稍微容易一些。现在我们需要生成此形状图像的 圆形阴影

  magick aqua_shape.png \
          -alpha Extract -blur 0x8  -shade 130x30 -alpha On \
          -background gray50 -alpha background -auto-level \
          aqua_shade.png
[IM Output]
处理 Alpha 背景的有趣行是将透明区域的隐藏颜色重置为中间色调的灰色,以便它不会影响颜色归一化。这可能非常重要。现在,我们将该阴影转换为看起来有点像水或玻璃气泡扭曲光线的方式的“照明效果”。

  magick aqua_shade.png \
          -function polynomial  3.5,-5.05,2.05,0.3 \
          aqua_lighting.png
[IM Output]
用于图像 曲线调整多项式函数。正是此函数提供了整体效果,并且可能难以确定。为此,我将此“曲线”所需的控制点传递给名为“im_fx_curves”的 IM 支持 shell 脚本。然后,它将返回适合这些控制点的“曲线”所需的多项式方程的“系数”。

  im_fx_curves -c -p  0,30  100,80  50,50  80,50  > aqua_coeffs.txt
[Gnuplot] ==>
[Coeffs]
此照明效果的最终调整是使照明效果的边缘更暗。

  magick aqua_lighting.png \
          \( +clone -alpha extract  -blur 0x2 \) \
          -channel RGB -compose multiply -composite \
          aqua_light+edge.png
[IM Output]
并且阴影叠加完成。剩下的就是使用 强光合成将其应用于原始图像。

  magick aqua_shape.png aqua_light+edge.png \
          -compose Hardlight -composite   aqua_result.png
[IM Output]
请注意,结果图像的最终整体颜色实际上是原始形状的原始颜色。实际上,您甚至可以将其应用于多色图像,而没有任何问题。因此,让我们在一条命令中重复上述所有步骤,包括创建初始形状图像。

  magick -background none -fill DodgerBlue \
          -font Candice -pointsize 96  label:'Aqua Text' -trim +repage \
          \
          \( +clone -bordercolor None -border 1x1 \
             -alpha Extract -blur 0x8  -shade 130x30 -alpha On \
             -background gray50 -alpha background -auto-level \
             -function polynomial  3.5,-5.05,2.05,0.3 \
             \( +clone -alpha extract  -blur 0x2 \) \
             -channel RGB -compose multiply -composite \
             +channel +compose -chop 1x1 \
          \) \
          -compose Hardlight -composite  aqua_text.png
[IM Output]
如果您仔细研究上述内容,您会发现所有先前概述的步骤都应用于生成照明图像,然后将其合成到原始图像上。

可平铺的星星和彗星

我想为各种目的制作一个随机星场的图块(星星具有可变强度)。这是我对这一点的缓慢改进尝试的结果。使用 随机噪声图像来稀疏自身以生成斑点图案。

  magick -size 100x100 xc: +noise Random -channel R -threshold 5% \
          -negate -channel RG -separate +channel \
          -compose multiply -composite   speckles.gif
[IM Output]
此图案是闪光动画效果的基础,也是其他效果的起点。例如,要制作星星,我们需要进一步修改其随机“斑点”图案,以使其更逼真。

  magick -size 100x100 xc: +noise Random -channel R -threshold 1% \
          -negate -channel RG -separate +channel \
          \( +clone \) -compose multiply -flatten \
          -virtual-pixel tile -blur 0x.4 -contrast-stretch .8% \
          stars.gif
[IM Output]
请注意,我不仅乘以了斑点蒙版(“R”通道),还将星强度图像(“G”通道)也乘以了两倍。这会导致像素强度呈平方衰减,因此存在的暗星多于亮星,就像在真实的夜空中一样。在此之后,我们通过 模糊根据其强度放大星星的大小。这会产生类似于星星燃烧到天文学家照相底片上的效果,使其更加逼真。模糊值越大,效果越大。最终的“-contrast-stretch”使结果恢复到可见状态。通过使用两个 随机噪声图像(一个用于蒙版,另一个用于星颜色),我们可以生成随机颜色的星星,而不是简单的灰度星星。

  magick -size 100x100 xc: +noise Random -channel R -threshold 1% \
          -negate -channel RG -separate +channel \
          \( xc: +noise Random \) -compose multiply -flatten \
          -virtual-pixel tile -blur 0x.4 -contrast-stretch .8% \
          stars_colored.gif
[IM Output]
但是,这可能需要更多工作,因为我们需要直接对颜色的强度进行平方,而不仅仅是将它们乘以线性分布。但是,它确实有效,并为进一步开发提供了起点。请注意,颜色不必是随机的,而是可以轻松地来自其他一些星星图像。例如,星颜色本身可以来自将用作最终背景的图像。现在我有了星景生成器,我可以简单地使用“-motion-blur”来创建一片流星雨!

  magick -size 100x100 xc: +noise Random -channel R -threshold .4% \
          -negate -channel RG -separate +channel \
          \( +clone \) -compose multiply -flatten \
          -virtual-pixel tile -blur 0x.4 -motion-blur 0x20+45 -normalize \
          star_fall.gif
[IM Output]
当然,我们希望星星更少,星强度“衰减”也更少。通过 极坐标扭曲图像,我们可以使彗星飞向或螺旋进入一个点!

  magick -size 250x100 xc: +noise Random -channel R -threshold .4% \
          -negate -channel RG -separate +channel \
          \( +clone \) -compose multiply -flatten \
          -virtual-pixel Tile -background Black \
          -blur 0x.6 -motion-blur 0x15-90 -normalize \
          +distort Polar 0 +repage  star_inward.gif
  magick -size 250x100 xc: +noise Random -channel R -threshold .4% \
          -negate -channel RG -separate +channel \
          \( +clone \) -compose multiply -flatten \
          -virtual-pixel Tile -background Black \
          -blur 0x.6 -motion-blur 0x15-60 -normalize \
          +distort Polar 0 +repage   star_spiral.gif
[IM Output]

[IM Output]
在这里,我们沿六个方向(成对)对星星进行运动模糊,然后将它们合并在一起以创建一个“星爆”场,就像您在玻璃镜片中看到的那样。

  magick -size 100x100 xc: +noise Random -channel R -threshold .2% \
          -negate -channel RG -separate +channel \
          \( +clone \) -compose multiply -flatten \
          -virtual-pixel tile  -blur 0x.3 \
          \( -clone 0  -motion-blur 0x10+15  -motion-blur 0x10+195 \) \
          \( -clone 0  -motion-blur 0x10+75  -motion-blur 0x10+255 \) \
          \( -clone 0  -motion-blur 0x10-45  -motion-blur 0x10+135 \) \
          -compose screen -background black -flatten  -normalize \
          star_field.gif
[IM Output]
请注意,较暗的星星只会产生一个小点,并且几乎没有“星爆”,而较大的亮星会产生非常大的“星爆”。现在,如果我能找到一种方法来添加“sinc()”类型的模糊,以便在最亮的星星周围也产生耀斑“环”,我们将拥有一个很棒的星场生成器。添加一些等离子体背景,我们甚至可以生成星云和气体云的假天文照片。通过将上述内容与 等离子体闪光动画结合起来,您可以制作出一组看起来像圣诞装饰品的星星。

  magick -size 100x100 xc: +noise Random -separate \
          null: \
            \( xc: +noise Random -separate -threshold 50% -negate \) \
            -compose CopyOpacity -layers composite \
          null: \
            plasma:red-firebrick plasma:red-firebrick plasma:red-firebrick \
            -compose Screen -layers composite \
          null:  \
            \( xc: +noise Random -channel R -threshold .08% \
              -negate -channel RG -separate +channel \
              \( +clone \) -compose multiply -flatten \
              -virtual-pixel tile  -blur 0x.4 \
              \( -clone 0  -motion-blur 0x15+90  -motion-blur 0x15-90 \) \
              \( -clone 0  -motion-blur 0x15+30  -motion-blur 0x15-150 \) \
              \( -clone 0  -motion-blur 0x15-30  -motion-blur 0x15+150 \) \
              -compose screen -background black -flatten  -normalize \) \
            -compose multiply -layers composite \
          -set delay 30 -loop 0 -layers Optimize       stars_xmas.gif
[IM Output]
上述技术只是可以实现的开端。使用一些简单的动画技术,可以创建闪光和随机耀斑,并将其添加到图像中。在 GIF 动画示例中提供了一个简单的示例,使用一个简单的 shell 脚本“star_field”来生成星爆。您可以用这个星生成器做什么?挑战:
  • 生成闪光而不是星星。初始斑点场应受蒙版限制(例如通过相乘)。然后,可以使用“屏幕”合成将闪光和星星叠加到图像上。
  • 使用蒙版“斑点场”为叠加生成星爆。通过对种子而不是完整的星爆进行蒙版,意味着星爆的“光线”可以离开蒙版区域以覆盖图像的其他部分。也就是说,光线不仅仅是“被切断”。
  • 创建随机星爆的动画。这可能需要您对单个星爆场进行魔术动画(可能带有旋转的光线)。
  • 通过生成一些星爆动画,您可以将它们合并在一起,形成一系列来自不同位置的重叠星爆。
  • 通过直方图拉伸和阈值化在图像最亮的部分找到一个唯一的“种子”点。然后挑选单个像素,直到一个像素击中蒙版区域。
  • 在扁平阴影形状的边缘创建星星。
如果您完成了上述任何挑战或将星生成器用于其他目的,请告知我和 IM 社区中的其他人。

径向耀斑

生成径向耀斑的实验。请注意,极坐标扭曲之前的初始图像宽度基本上决定了将产生的光线数量。

  magick -size 100x1 xc: +noise Random -channel G -separate +channel \
          -scale 100x100\!                                +write flare_1a.png \
          \( -size 100x100 gradient:'gray(100%)' -sigmoidal-contrast 10x50% \) \
          -colorspace sRGB -compose hardlight -composite  +write flare_1b.png \
          -virtual-pixel HorizontalTileEdge -distort Polar -1 \
          flare_1_final.png
[IM Output] ==> [IM Output] ==> [IM Output]
请注意,我如何使用“+write”保存中间图像以进行显示。这是一种调试技术,在 复杂图像处理和调试中进行了详细介绍。这是另一个使用多个叠加来实现不同外观耀斑的示例。请注意用于生成中间调试和示例图像的技术,以及显示所涉及步骤的图像。

  magick -size 100x1 xc: +noise Random -channel G -separate +channel \
          -size 100x99 xc:black -append -motion-blur 0x35-90 \
          \( -size 100x50 gradient:'gray(0)' \
             -evaluate cos .5 -sigmoidal-contrast 3,100% \
             -size 100x50 xc:'gray(0)' -append \) \
          \( -size 1x50 xc:'gray(0)' \
             -size 1x1 xc:'gray(50%)' \
             -size 1x49 xc:'gray(0)' \
             -append -blur 0x2 -scale 100x100\! \) \
          \
          -scene 10 +write flare_2%x.png \
          \
          -background 'gray(0)' -compose screen -flatten +write flare_2f.png \
          \
          -virtual-pixel HorizontalTileEdge -distort Polar -1 \
          -colorspace sRGB flare_2_final.png
[IM Output] [IM Output] [IM Output] ==> [IM Output] ==> [IM Output]
使用极坐标扭曲生成耀斑图像的主要问题是光线随着半径的增加而变宽,而实际上我们希望它们保持大致恒定的宽度并变暗,或者至少变细。欢迎提供想法和建议
颜色着色在这类图像中也可能很重要。例如,这里我 对中间色调颜色进行蓝色着色

  magick flare_2_final.png  -fill SkyBlue  -tint 100%  flare_2_color.png
[IM Output]
-tint”操作使用的百分比也可以用于调整光线和耀斑环的强度,尽管它不会改变图像的白色核心太多。这些示例在 IM 论坛讨论 使用径向耀斑作为蒙版中得到了进一步的探讨。