ImageMagick 示例 --
多图像层
- 索引
-
ImageMagick 示例前言和索引
-
层简介
-
附加图像 (-append)
-
多个图像对的合成
- 使用合成命令 (composite, -geometry)
- Convert 的合成操作符 (-composite, -geometry)
- 绘制多个图像 (-draw 'image ..')
-
多个图像的分层
-
图像分层示例
-
评估序列多图像合并
-
多项式 - 使用多项式合并多图像
图像分层简介
正如我们之前提到的,ImageMagick 不仅处理单个图像,还处理图像序列或列表。这允许您在两种非常特殊的图像处理技术中使用 IM。例如,您可以将列表中的每个图像视为时间中的单个帧,因此整个列表可以被视为一个动画。这将在其他 IM 示例页面中探讨。参见动画基础。或者,您可以将序列中的每个图像视为一组透明投影胶片的图层。也就是说,每个图像都表示最终图像的一小部分。例如:第一层(最底层)可以表示背景图像。在其之上,您可以有一个模糊的透明阴影。然后下一层图像包含投射该阴影的对象。在此之上,有一层带有覆盖该对象的一些文本。也就是说,您可以有一系列图像或“层”,每个层都为更复杂的图像添加一个片段。每个图像层可以独立于任何其他层进行移动、编辑或修改,甚至可以保存到多图像文件(例如 TIFF:、MIFF: 或 XCF:) 或作为单独的图像,以便将来处理。这就是图像分层的意义所在。只有在创建所有图像层后,您才能扁平化、马赛克或合并所有分层图像到单个最终图像中。追加图像
追加可能是处理多个图像提供的多图像操作中最简单的。基本上,它将内存中当前的图像序列连接成一列或一行,没有任何间隙。"-append
" 选项垂直追加,而加号形式 "+append
" 水平追加。例如,这里我们将一组字母图像并排追加在一起,形成一个花哨的单词,类似于“字体”的单个“字形”或字母是如何连接在一起的。
magick font_A.gif font_P.gif font_P.gif font_E.gif font_N.gif \ font_D.gif font_E.gif font_D.gif +append append_row.gif |
![[IM Output]](append_row.gif)
+append
" 操作符是如何作为最后一个操作完成的,在将您要追加的所有图像都添加到当前图像序列之后。这非常适合例如将标签追加到图像上……
|
![]() |
-background
" 颜色用于填充未填充的任何空间。当然,如果所有图像的宽度都相同,则不会为这种填充留下空间。从 IM v6.4.7-1 开始,可以使用 "-gravity
" 设置指定应如何将图像组合在一起。因此,在垂直追加中,'Center
' 设置会相对于最终结果图像将图像居中('North
' 或 'South
' 设置也会这样做)。
|
![]() |
East
' 重力设置都将图像与右侧对齐。
|
![]() |
+append
" 时,可以实现类似的垂直对齐。![]() ![]() |
在 IM v6.4.7 之前,对齐追加图像要困难得多,并且通常涉及使用 "-flop " 进行右侧对齐。或者使用 "-extent " 或 "-border " 调整图像宽度以进行居中对齐的追加。例如,这将适用于旧版本的 IM 6.3.2……
|
|
![]() |
|
![]() |
![]() ![]() |
当与 UNIX shell 一起使用时,上面的括号必须用引号括起来或用反斜杠 ('\ ') 转义,否则 shell 会将其解释为完全不同的东西。 |
![]() ![]() |
由于仅涉及两个图像,因此我们可以使用 "+swap " 或 "-reverse " 而不是使用括号。 |
追加图像数组
您可以进一步操作以创建整个图像数组,并按行或列构建它们。蒙太奇连接模式,了解创建相同大小图像数组的另一种方法。![]() ![]() |
"-append " 操作符只会追加实际的图像,并且不使用虚拟画布(图像页面)大小或图像偏移量。但是,虚拟画布信息似乎处于一种奇怪的状态,画布大小加在一起,偏移量设置为某个未定义的值。这可能被视为一个错误,这意味着在保存之前或在这些信息可能变得重要的操作中使用图像之前,应使用 " +repage " 重置输入图像或结果的虚拟画布。这种情况可能会在操作的未来扩展中得到修复。因此建议谨慎操作,尤其是在重新追加平铺裁剪图像时。 |
带重叠的追加
在 IM 论坛上,一位用户请求了一种简单的方法来以某种重叠方式追加图像。提供了许多解决方案。这是最简单的解决方案之一,重叠量在一个位置给出。
|
![]() |
压缩追加
追加图像的另一种方法是压缩。 "-smush " 操作符的工作方式与追加操作符(见上文)非常相似,但它接受一个参数,表示图像之间需要多少空间(或反空间)。例如,让我们用它来更简单地显示前面的示例。
|
![]() |
A
”和“V
”并将其“压缩”在一起,并在它们之间留出尽可能小的空间。
|
![]() |
-smush
" 的设计目的,尽管它需要大量的计算,因此比追加(见上文)慢得多。参数是该最终位置的偏移量,通常是正值以生成间隙,但可以是负值以创建重叠。
|
![]() |
多个图像对的合成
合成是用于将两个单独的图像合并在一起的低级操作。几乎所有分层技术最终都会分解为一次合并两个图像,直到只剩下一个图像为止。因此,让我们首先了解如何执行图像对的低级合成。使用合成命令
使用 ImageMagick 将两个图像组合在一起的传统方法是通过 "magick composite
" 命令。此命令一次只能组合两个图像,并将每个操作的结果保存到文件中。当然,这并不能阻止您一次一个地使用它来分层多个图像……
|
![]() |
![]() ![]() |
由于 ImageMagick 在打开输出图像之前读取所有输入图像,因此您可以输出到其中一个输入图像。这允许您像上面显示的那样,反复处理同一图像,而不会出现问题。 不要对像“JPEG”这样的有损图像格式执行此操作,因为格式错误是累积的,并且基础图像会很快退化。 |
-geometry
" 设置对其进行定位。
|
![]() |
magick composite
" 命令还有一些其他优点,您可以使用 "-compose
" 选项控制图像绘制到背景的方式,其相对位置受 "-gravity
" 设置影响。您还可以 "-tile
" 叠加层,使其仅覆盖背景图像,而无需指定平铺限制。这只有在使用 "magick composite
" 时才可用。这种方法的主要缺点是您使用了多个命令,并且 IM 必须将工作图像写入管道或磁盘,以便下一个命令再次读取。要查找更多使用 "magick composite
" 命令将图像叠加到其他图像上的示例,请参阅 "通过叠加图像进行注释" 和 "使用重力进行图像定位"。 Convert 的合成运算符
"-composite
" 运算符可在 "magick
" 命令中使用。有关更多详细信息,请参阅 IM 中的图像合成。这允许您执行与上述相同操作,但所有操作都在一个命令中完成。
|
![]() |
skyblue
",然后将后续每个图像分层到该画布上的给定位置。现在 "-geometry
" 是一个非常特殊的运算符,它不仅为下一个 "-composite
" 操作设置叠加位置,还会 "-resize
" 当前图像序列中的最后一个图像(且仅限最后一个图像)。
|
![]() |
-geometry
" 的这种“调整大小”副作用,即使它很方便。基本上,因为它更像是向后兼容的效果,并且在某些情况下可能会产生其他影响。以下是更详细的建议...
|
![]() |
绘制多个图像
同样使用 "magick
",您还可以使用 绘制图元 将图像叠加到其工作画布上。
|
![]() |
|
![]() |
-gravity
" 影响,就像文本一样。分层多个图像
图像的真正分层需要方法将多个图像组合在一起,而无需单独合成每对图像。这就是各种-layers
运算符方法发挥作用的地方。分层图像的顺序可能很重要,因此了解特殊的 图像序列或列表运算符 是一个好主意。请注意,“分层图像”实际上与处理“动画帧”相同。因此,建议您还查看 动画基础知识 和 动画修改,以了解涉及处理单个“图层”或“帧”的技术。实际上,动画通常使用相同的 -layers
运算符来处理图像。 扁平化 - 到背景图像上
"-layers flatten
" 图像列表运算符(或其快捷方式 "-flatten
")基本上会将给定的每个图像 "合成
" 到背景上,以形成单个图像。但是,图像位置是使用其当前的 虚拟画布或页面 偏移量指定的。例如,这里我创建了一个漂亮的画布,并指定了我想要叠加到该画布上的每个图像。
|
![]() |
![]() ![]() |
从 IM v6.3.6-2 开始,"-flatten " 运算符仅是 "-layers 'flatten' " 方法的别名。因此," -flatten " 选项可以被视为同名 "-layers " 方法的快捷方式。 |
-flatten
" 为您创建一个。画布颜色将是当前的 "-background
" 颜色,其大小由第一个图像的 虚拟画布 大小定义。
|
![]() |
![]() ![]() |
虽然 "-gravity " 设置会影响使用 "-geometry " 设置定义的图像放置,但它不会影响使用 "-page " 设置设置的 虚拟画布偏移量 进行的图像定位。这是此类偏移量定义的一部分。有关更多详细信息,请参阅 几何形状与页面偏移量。如果需要使用 " -gravity " 进行放置,请查看上述多图像合成方法,或查看可以同时处理这两种定位方法的特殊 图层合成 方法。 |
|
![]() |
|
![]() |
![]() ![]() |
不建议使用 展平 添加生成的 阴影图像,因为生成的阴影图像可能具有负图像偏移量。 如 阴影图像 部分中所述,建议的解决方案是使用稍后将介绍的更高级的 图层合并 技术。 |
|
![]() |
奇怪的是,完全相同的处理也可以用于“裁剪”或 裁切 图像到小于原始图像的虚拟画布。但是,在这种情况下,您需要使用负偏移量来定位“裁剪”位置,因为您正在偏移图像而不是定位裁剪“窗口”。
|
![]() |
-flatten
" 也执行的操作。如果图像仅部分包含在该查看窗口中,它也不会“扩展”图像本身以覆盖整个视口。 "-flatten
" 运算符的一个常见误用是 移除图像的透明度。也就是说,去除图像可能具有的任何透明度,但将其叠加在背景颜色上。但是,当涉及多个图像时,此方法将不起作用,因此不再推荐。 马赛克 - 画布扩展
"-layers mosaic
" 运算符(或其 "-mosaic
" 快捷方式)更像是 展平运算符 的扩展画布版本。与其仅根据初始图像的画布大小创建初始画布,马赛克运算符 会创建一个足够大的画布以容纳所有图像(仅在正方向)。例如,这里我甚至没有设置适当的 虚拟画布,但是 "-mosaic
" 运算符将计算出容纳所有图像图层所需的画布大小。
|
![]() |
![]() ![]() |
在 IM v6.3.6-2 上,"-mosaic " 运算符仅是 "-layers 'mosaic' " 的别名。因此," -mosaic " 选项可以被视为同名 "-layers " 方法的快捷方式。 |
-mosaic
" 和 "-flatten
" 仍然会创建一个从“原点”或 0,0 像素开始的画布。这是图像“虚拟画布”或“页面”定义的一部分,因此您可以确保这两个运算符的最终图像都不会有虚拟偏移量,并且整个画布将完全以实际像素数据定义。另请注意,"-mosaic
" 仅扩展正方向(底部或右侧边缘)的画布,因为顶部和左侧边缘固定在虚拟原点。当然,这意味着 "-mosaic
" 仍然会裁剪具有负偏移量的图像...
|
![]() |
合并 - 创建新的图层图像
"-layers merge
" 运算符几乎与之前的运算符相同,并且是在 IM v6.3.6-2 中添加的。它仅创建一个足够大的画布图像以容纳所有给定图像及其各自的偏移量。像 马赛克 一样,它也会扩展画布,但不仅在正方向,而且在负方向。基本上,这意味着在将图层图像合并在一起时,您无需担心裁剪、偏移或其他方面。所有图像都将相对于彼此的位置合并。输出不包括或确保原点是扩展画布的一部分。因此,图层合并 的输出可能包含“图层偏移量”,该偏移量可能是正数或负数。换句话说..图层合并 合并图层图像以生成新的图层图像。因此,如果您在完成时不希望出现该偏移量,您可能希望在最终保存之前包含 "+repage
" 运算符。例如,以下是我们之前使用过的相同图层图像集...
|
![]() |
|
![]() |
+repage
”操作符会移除最终图像中的绝对虚拟画布偏移,只保留图像之间相对的位置。偏移被移除是因为网页浏览器通常难以处理图像偏移,尤其是负图像偏移,除非它是GIF动画的一部分。但是,如果我不移除该偏移,所有图像都将保留在其在生成的单层图像的虚拟画布上的正确位置,允许您继续处理并将更多图像添加到合并的图像中。通常,您会使用“-background
”颜色“None
”,使合并图像的未用区域透明。当应用于单个图像时,图层合并将用纯色背景替换图像中的任何透明度,但会保留图像的原始大小,以及图像中的任何偏移。但是,图像的虚拟画布大小可能会调整为“最佳匹配”该图像的大小和偏移。该操作符最初的目的是允许用户更轻松地将多个失真图像合并成一个统一的整体,而不管各个图像的偏移如何。例如,当对齐照片以形成更大的“全景”时。您可以简单地从一个中心未失真的基础图像(没有偏移)开始,并使用此操作符将其他图像叠加到该起始点周围(使用负或正偏移),这些图像已对齐并失真以匹配该中心图像。有关通过失真图像对齐公共控制点来使用此操作符的其他示例,请参阅3D等距照片立方体和3D透视盒。使用此操作符的其他示例是生成一系列简单的重叠照片。The operation "-layers trim-bounds
" can be used to ensure all
images get a positive offset on a minimal canvas size, while retaining there
relative positions, and without actually layer merging the images into one
final image.
This lets you then perform further processing of the images before they are
actually merged, such as placing more images relative to the that image group
but looking up the resulting virtual canvas bounds.
However if images have a transparency, it is probably a good idea to trim
that transparency from images first, making the ideal usage...
-alpha set -bordercolor none -border 1x1 -trim -layers trim-bounds
This minimizes the image layers including any and all transparent areas of
actual image data, while ensuring everything is contained on a valid
virtual (positive) canvas of minimal size.
合并合成 - 渐进分层
“-layers coalesce
”图像操作符(或其“-coalesce
”快捷方式)实际上是为将GIF动画转换为一系列图像而设计的。例如,有关详细信息,请参阅合并动画。但是,它与“-flatten
”密切相关,并且在这方面对多层图像具有非常有用的效果。例如,对单个图像使用合并,将执行与使用扁平化和“-background ”颜色“None ”或“Transparency ”完全相同的工作。也就是说,它将用透明像素“填充”图像的画布。
|
![]() |
magick \( -page 100x100+5+10 balloon.gif \) \( -page +35+30 medical.gif \) \ \( --page +62+50 present.gif \) \( -page +10+55 shading.gif \) \ -set dispose None -coalesce miff:- |\ montage - -frame 4 -tile x1 -geometry +2+2 \ -background none -bordercolor none coalesce_none.gif |
![[IM Output]](coalesce_none.gif)
-set
”所有“-dispose
”设置到“None
”。这有效地告诉“-coalesce
”只需将每个帧叠加到先前叠加结果的顶部。结果是第一个图像只是图像画布的“填充”,带有透明背景。下一个图像是带有该图层叠加的先前图像。以此类推。图像序列的“渐进”扁平化。因此,序列中的最后一个图像将与使用透明背景进行正常的“-flatten
”相同。如果您使用了“-dispose
”设置“Background
”,则可以获得完全不同的效果。在这种情况下,“-coalesce
”只会“填充”每个图像的画布,就好像它们是完全独立的图像一样!
magick \( -page 100x100+5+10 balloon.gif \) \( -page +35+30 medical.gif \) \ \( --page +62+50 present.gif \) \( -page +10+55 shading.gif \) \ -set dispose Background -coalesce miff:- |\ montage - -frame 4 -tile x1 -geometry +2+2 \ -background none -bordercolor none coalesce_bgnd.gif |
![[IM Output]](coalesce_bgnd.gif)
-coalesce
”操作符不会使用当前的“-compose
” Alpha合成设置。它仅使用“Over
”合成方法,因为这是GIF动画处理所需的。在下一组示例中,我们将介绍如何使用不同的“-compose
”方法与更标准的图像分层操作符。 合成方法和分层
三种分层方法:扁平化、马赛克和合并;将使用“-compose
”设置来确定用于依次叠加每个图像的合成方法。因此,您可以将这些函数视为一个多图像“-composite
”操作符,它能够设置指定颜色的初始“-background
”画布。但是,使用除默认的Alpha合成“Over
”之外的任何内容都需要在应用之前进行思考,否则您将得到意外的结果。您可能还需要考虑“-background
”颜色对这些操作符用于生成起始画布的影响,每个图像(包括第一个)都在该画布上进行合成。例如,让我们将每个后续图像放置在先前图像的下方,使用“DstOver
”...
|
![]() |
|
![]() |
正如您所看到的,上面图像处理比您通常在阴影生成中看到的更简单、更清晰,只需按顺序(使用透明起始画布)将每个图像下移。
当然,我也可以很容易地反转图像列表。
|
![]() |
Xor
”合成方法将它们叠加,则您将获得一个不寻常且复杂的符号,并且工作量最少。
|
![]() |
图层合成 - 合并两个图层列表
使用IM v6.3.3-7,“-layers
”方法“Composite
”被添加,允许您将两个完全独立的图像集组合在一起。要在命令行上执行此操作,需要一个特殊的“null:
”标记图像来定义第一个目标图像列表在哪里结束以及叠加的源图像列表在哪里开始。但这是此方法唯一真正的复杂之处。基本上,第一个列表中的每个图像都与第二个列表中的对应图像合成,有效地将这两个列表合并在一起。第二个列表可以使用几何偏移相对于第一个列表全局定位,就像使用正常的合成操作符一样(见上文)。重力也使用第一个图像的画布大小来进行计算。在此“全局偏移”之上,还保留了图像的各个虚拟偏移,因为每对图像都合成在一起。还处理了一种特殊情况。如果其中一个图像列表仅包含一个图像,则该图像将与另一个列表中的所有图像合成。此外,在这种情况下,将保留较大列表的图像元数据(例如动画时间),即使它不是合成的目标端。此分层操作符通常用于合成两个动画时,可以将其视为一种时间分层图像列表。因此,它在示例的动画修改部分中得到了更好的示例。因此,有关更多详细信息,请参阅多图像 Alpha合成。
处理图像图层
使用上面各种图层操作符叠加多个图像是一种非常通用的技术。它允许您分别处理大量图像,然后在完成后将它们全部组合成一个统一的整体。到目前为止,我们已经展示了以多种不同方式合并(合成或分层)多个图像的各种方法。在这里,我提供了一些关于如何使用这些技术的更实用的例子。缩略图的分层
您还可以使用此技术以各种复杂的方式合并多个缩略图。在这里,我添加了柔和边缘到图像中,当您阅读和定位它们时,您可以在平铺画布上生成相当不错的图像组合。
magick -page +5+5 holocaust_tn.gif \ -page +80+50 spiral_stairs_tn.gif \ -page +40+105 chinese_chess_tn.gif \ +page \ -alpha Set -virtual-pixel transparent \ -channel A -blur 0x10 -level 50,100% +channel \ \( -size 200x200 tile:tile_fabric.gif -alpha Set \) -insert 0 \ -background None -flatten overlap_canvas.jpg |
![[IM Output]](overlap_canvas.jpg)
图像的计算定位。
可以在多种方式中设置虚拟画布偏移(页面)。更具体地说,您可以“-set
”设置每个图像的属性,甚至可以为每个图像计算不同的位置。例如,这里我读取了一组大型图像(所有相同大小的小图标图像)并将它们排列成一个圆圈。
magick {balloon,castle,eye,eyeguy,ghost,hand_point,medical}.gif \ {news,noseguy,paint_brush,pencil,present,recycle}.gif \ {shading,skull,snowman,storm,terminal,tree}.gif \ \ -set page '+%[fx:80*cos((t/n)*2*pi)]+%[fx:80*sin((t/n)*2*pi)]' \ \ -background none -layers merge +repage image_circle.png |
![[IM Output]](image_circle.png)
-set page
”操作,它使用标准化的图像索引(FX表达式 't/n
')为每个单独的图像创建一个从 0.0 到略小于 1.0 的值。然后将此值映射到使用FX表达式作为百分比转义在半径为 80 像素的圆圈中定位图像(通过角度)。计算出的位置是图像的左上角(而不是其中心,尽管这只是一个简单的调整),然后合并以生成新图像。定位不考虑偏移量是正数还是负数,这是合并图层运算符的功能。也就是说,我们生成了一个所有图像彼此相对的新图像。最终的“+repage
”删除了合并图层图像的最终结果负偏移量,因为这不再需要并且在查看结果图像时可能会导致问题。请注意,第一个图像(结果中最右边的图像)位于其他每个图像的下方。如果您希望分层真正循环,以便最后一个图像位于第一个图像下方,您可能需要将第一个图像分成两半,并将上半部分放在序列的末尾,以便第一个图像的上半部分覆盖最后一个图像,而下半部分保持在第二个图像下方。这种技术功能强大,但它只能将图像定位到整数偏移量。如果您需要更精确的图像亚像素定位,则需要将图像扭曲(平移)到精确的亚像素位置,而不仅仅是调整其虚拟偏移量。增量计算的位置
在设置图像属性时,您可以使用 FX 表达式访问其他图像的一些图像属性。这意味着您可以设置每个图像的位置,相对于先前图像的计算位置。例如,这将每个图像的位置设置为前一个图像的右侧。也就是说,前一个图像的位置加上其宽度。
magick rose: netscape: granite: \ \ +repage -set page '+%[fx:u[t-1]page.x+u[t-1].w]+0' \ \ -background none -layers merge +repage append_diy.png |
![[IM Output]](append_diy.png)
page
”(虚拟偏移量)属性。结果是 DIY 追加运算符 等效项,并且您可以从中开发自己的变体。您应该注意,整个序列实际上由在第一个图像的位置计算期间设置的“u[-1].w
”移动。这应该是当前图像序列中最后一个图像的宽度。但是,该整体位移由最终的“+repage
”丢弃。您可以使用一些额外的计算来忽略此偏移量,但在上面不需要。![]() ![]() |
当使用图像索引(如“u[t] ”)时,所有图像选择器“u ”、“v ”和“s ”都引用相同的图像,根据给定的“[index] ”。因此,最好使用“u ”(第一个或第零个图像)作为此索引行为的助记符(以及在发生更改时)。有关更多信息,请参阅FX,DIY 图像运算符。 |
magick font_[0-9].gif \ -set page '+%[fx:u[t-1]page.x+u[t-1].w-8]+%[fx:u[t-1]page.y+4]' \ -background none -layers merge +repage append_offset.gif |
![[IM Output]](append_offset.gif)
图像的两阶段定位
您可以简化图像处理,将其分成两个步骤。一个步骤可用于生成、扭曲、定位和向图像添加内容,最后一步将它们全部合并在一起。例如,让我们从照片商店中较大的原始图像创建宝丽来缩略图,分别处理每个图像(保持该方面独立且简单)。
|
![[IM Output]](overlapped_polaroids.jpg)
-repage
”运算符,请参阅画布偏移量),以便生成的每个图像都恰好位于前一个图像右侧 60 像素。也就是说,每个图像的中心都相隔固定距离,而不管图像的实际大小如何,由于纵横比和旋转,图像的大小可能已发生变化。此脚本的另一个主要技巧是,您无需将每个“图层图像”保存到临时文件中,而只需使用MIFF:文件格式将图像写入管道。一种称为MIFF 图像流的方法。这之所以有效,是因为“MIFF:
”文件格式允许您将多个图像简单地连接到单个数据流中,同时保留所有图像元数据,例如其虚拟画布偏移量。此技术为许多其他脚本提供了一个良好的起点。可以生成或修改图像,并且可以根据需要以任何方式计算最终大小和位置。另一个示例是脚本“hsl_named_colors
”,它获取在 ImageMagick 中找到的命名颜色的列表,并将它们排序到 HSL 色彩空间中这些颜色的图表中。您可以在颜色规范中查看其输出。其他可能性包括...- 使用任何类型的缩略图(或其他内容),或者只是直接使用原始的小缩略图。
- 生成图像,使第一个图像居中,其他图像排列在第一个图像的左右下方,就像金字塔一样。
- 通过将图像放置在彼此相对的特定 X 和 Y 坐标上,将图像定位到弧线、圆圈和螺旋线上。例如:PhD 圆圈、日落花、斐波那契螺旋。
- 根据图像的颜色定位图像。例如:书籍封面。
- 按一天中的时间或提交时间定位图像。例如:日落之年
地图上的图钉
这是一个典型的分层示例,在特定位置的地图上放置彩色图钉。![[IM 输出]](../images/push_pin.png)
+18+41
。我还有一个威尼斯地图的图像,并且想要在地图上的各个点放置图钉。例如,“学院美术馆”位于像素位置+160+283
。要使图钉与该位置对齐,您需要从地图位置减去图钉末端的位置。这为我们的“图钉”图像产生了+142+242
的偏移量。以下是使用分层图像的结果此示例来自 IM 论坛讨论使用 Convert 分层图像。让我们进一步自动化此过程。我们有一个文件列出了我们想要在地图上放置的每个图钉的位置和颜色。文件中的位置名称未使用,只是对列出的像素位置的参考注释。
让我们读取此文本文件,以便在循环中创建“图钉”。
|
![[IM Output]](map_venice_pins.jpg)
magick
”命令。图像扭曲动画中的脚本使用此技术。这两种方法都避免了生成临时图像的需要。阴影层
在重叠图像集中正确处理半透明阴影效果实际上比看起来要困难得多。仅将照片与阴影叠加会导致阴影应用两次。也就是说,两个重叠的阴影变得非常暗,而在现实中,它们不会像重叠图像那样以完全相同的方式重叠。图像的各个部分应该只是阴影或没有阴影。也就是说,阴影应该只应用一次到图像的任何部分。除非您有两个独立的光源,否则您不应该获得更暗的区域,这会使事情变得更加困难。Tomas Zathurecky < tom @ ksp.sk > 接受了处理分层图像中阴影效果的挑战,并开发了图像累加器技术来解决此问题。基本上,我们需要一次将每个图像添加到堆栈的底部。当我们添加新图像时,所有先前图像的阴影都需要使新图像变暗,然后才能将其添加到堆栈中。但是,只需要添加落在新图像上的阴影。不落在新图像上的阴影需要忽略,直到以后落在其他图像或背景(如果有)上。这是一个示例...
|
![]() |
-size 1x1 xc:none
”)开始。现在,要将新图像添加到图像堆栈的底部,我们每次都应用相同的操作集...- 首先将缩略图图像读入内存,并应用任何旋转、相对位置(可能是负数)。如果需要,您也可以在此处对图像应用其他缩略图操作,尽管在本例中,这些操作已经执行过了。新图像形成图像索引 #1。
- 现在我们获取之前的图像堆栈(#0),并生成一个具有适当颜色、模糊度、偏移量和环境光百分比的阴影。
- 此阴影叠加在新图像(#1)上,因此只保留落在新图像“
ATop
”上的阴影。我们还可以(可选)对结果应用裁剪操作,以去除阴影操作添加的任何额外空间,从而形成图像 #2。 - 现在我们只需将新图像(#2)添加到累积的图像堆栈(#0)中。
- 并删除所有以前的中间图像,除了最后一个。
现在,以上方法可以正确处理多层图像阴影,但在阴影偏移时,实际上所有图像的偏移量都相同!真正应该发生的是,随着阴影落在越来越深的图像上,阴影应该变得更加偏移,也更加模糊。也就是说,顶部的图像应该在背景上产生非常模糊的阴影,而最底部的图像则不然。这实际上更难做到,因为您不仅需要跟踪图像堆栈,还需要跟踪随着图像堆栈变大,阴影变得“模糊”的程度。因此,您确实需要两个累加器。图像堆栈(如上所述)和阴影累加,当我们添加更多图像时。例如,以下是一组相同的图像,但阴影随着深度变得更加模糊。
|
![]() |
70x0+0+0
”)。然后将新图像添加到累积的图像堆栈(#0)中。但在将新图像(#2)的阴影直接添加到累积的阴影(#1)之后,同样没有模糊或偏移,然后我们才模糊和偏移所有阴影,以形成新的累积阴影图像。换句话说,随着堆栈越来越厚,累积的阴影图像变得越来越模糊和偏移。只有较深图像的阴影没有累积太多效果。此程序本质上将阴影的应用与增量的阴影累加器分离。这允许您控制诸如……- 逼真的阴影(如上所示):70x0+0+0 和 100x2+4+7
- 恒定阴影(作为基本示例):70x2+4+7 和 100x0+0+0
- 恒定模糊,但累积偏移:70x2+0+0 和 100x0+4+7
- 恒定和渐进偏移:60x0+4+7 和 100x0+1+1
- 累积环境光效果:80x0+0+0 和 95x2+4+7
-compose ATOP
”合成之前设置“-background
”颜色将允许您定义阴影的颜色(实际上是彩色环境光)。您甚至可以使用不同的颜色来表示最终落在最终背景层上的阴影(最后的“-background black
”设置),或者完全将其关闭以使其看起来像图像根本没有位于任何背景之上(即悬浮在空中)。它非常通用。Tomas Zathurecky 继续开发了另一种处理分层图像阴影的方法,通过将分层图像列表作为一个整体进行处理。我自己以前从未想过这种方法。这种方法的优点是可以将整个图像列表作为一个整体进行处理,而不必一次累积一个图像,并一遍又一遍地重复相同的操作块。首先,让我们再次看看更简单的“恒定阴影”问题。
|
![]() |
-layers trim-bounds
”开始,这是一个边界裁剪操作,它扩展所有图像的虚拟画布以包含所有图像,并确保所有偏移量都为正。然后将其克隆、合并并进行阴影处理,以创建单独的渐进阴影列表。现在,我们可以使用图层合成将阴影和原始图像列表合并在一起。这里的问题是,在合并之前,我们不仅需要添加一个特殊的“null:
”标记图像来分隔这两个列表,还需要添加一个特殊的空白图像“xc:none
”来偏移阴影列表。这样每个阴影图像将“ATop
”叠加在原始列表的下一个图像上。剩下的就是从下到上(反转)顺序合并现在已正确阴影的图像。处理“深阴影”需要图层计算。
|
![]() |
![]() ![]() |
使用 IMv7 的“magick”命令,以上操作将变得简单得多,这将允许您直接在“-shadow ”的参数中使用“fx 计算”,这不仅可以让您根据深度计算更大的阴影偏移量,还可以让您根据深度使阴影更加模糊。 |
定位扭曲透视图像
对齐扭曲的图像可能很棘手,这里我将研究如何对齐此类图像以匹配非常特定的位置。这里我有两张图像,突出显示每张图像上的特定点。 第二张图像是 65% 半透明的,这允许您在将其合成到蓝色图像上时透视它,以便您可以查看标记点是否对齐。标记的控制点本身分别位于坐标59,26
(蓝色)和 35,14
(红色)。如果您只是将两张图像叠加,则只需减去偏移量并“合成”这两张图像,产生 +24+12
的偏移量。
|
![]() |
扭曲图像时,您需要确保这两个像素保持对齐。最好的方法是使用您想要对齐的点作为扭曲控制点。这将确保它们被正确放置。
|
![]() |
|
![]() |
+repage
”来执行此操作。如果我要进行进一步处理(无需在网络上显示结果),我会保留该偏移量(删除“+repage
”),以便图像位置保留在正确且已知的位置以供以后处理。现在,如果要进行更复杂的扭曲(例如透视),则上面显示的相同技术也适用。
|
![]() |
|
![]() |
|
![]() |
null:
”图像文件格式输出。我们还告诉扭曲它正在生成的新的图像仅为一个像素大小,使用扭曲视口。这样,它会执行扭曲准备和详细报告,然后只扭曲单个“目标”像素,然后将其丢弃。这可以节省大量处理时间。实际上,如果扭曲没有使用源图像元数据(用于百分比转义“%w
”和“%h
”)作为其计算的一部分,我们甚至不需要源图像“align_red.png
”。在这种情况下,我们也可以对输入图像使用单个像素“null:
”图像。对于此信息收集步骤,我们实际上并不关心虚拟像素、背景或任何其他内容,因此我们无需担心设置这些功能。
现在我们可以获取失真信息,我们需要从输出的第 3 行和第 4 行提取 8 个透视系数。然后可以使用这些系数将红色控制点映射到其新的失真位置,并从中减去蓝色控制点,以便获得所需的实际平移量,以使标记的红色坐标与蓝色坐标对齐。
|
![]() |
tr
”文本过滤器从输出中删除额外的引号和逗号。然后它使用“awk
”程序提取系数,并执行将红色标记“前向映射”以匹配蓝色标记所需的浮点数学运算。请注意,我又向控制点的“像素坐标”添加了 0.5,以确保计算使用像素的中心。参见 图像坐标与像素坐标。现在我们知道了失真图像所需的平移量,我们有两种方法可以将该平移添加到失真中。可以通过适当地修改透视投影的系数(不容易)。或者我们可以只将平移量添加到原始图像的目标坐标的每一个中(非常容易)。以下是后一种方法的结果(将平移添加到目标坐标中)...
|
![]() |
在右侧,我已经裁剪并缩放了控制点周围的结果,以显示它们完美对齐!
|
![]() |
在 使用失真进行文本定位 中探讨了一个类似但更简单的问题。
评估序列 - 直接多图像合并方法
"-evaluate-sequence
" 方法旨在以非常特定的方式将多个相同大小的图像合并在一起。在某些方面,它是 评估和函数运算符 与我们上面看到的多分量 合成 技术的混合。许多提供的方法甚至可以使用普通的多图像分层合成技术来执行,但并非所有方法都可以。该运算符使用与“-evaluate
”相同的方法,因此您可以使用“-list Evaluate
”获取它们的列表。尽管其中一些(例如“Mean
”和“Medium
”)在与该运算符一起使用时才真正有用。 多个图像的平均值
从本质上讲,较旧的“-evaluate-sequence mean
”和较新的“-evaluate-sequence mean
”都将创建所有提供的图像的平均值。例如,以下是使用玫瑰图像的所有 翻转和翻转 版本计算的平均值。
|
![]() |
composite -blend 50%
”图像操作,它可以处理两个不同大小的图像。有关更多详细信息,请参见 将两个图像混合在一起 的示例。 IM 讨论论坛 讨论了 每次平均 10 帧的序列,以便平均数千张图像,而不会占用计算机内存(使其变得非常缓慢)。与此相关并包含相关数学的是讨论 不要一次加载所有图像。使用“mean
”的另一种方法是使用较新的 Poly 运算符,它可以分别对每个图像加权。 多个图像的最大/最小值
“Max
”和“Min
”方法将从图像序列中获取最大(较亮)值和最小(较暗)值。同样,它们基本上等同于使用 亮化和暗化合成方法,但使用多个图像。通过正确选择背景画布颜色,您可以使用 Flatten 运算符 以及等效的合成方法。
|
![]() |
|
![]() |
按强度计算的中值像素
“-evaluate-sequence Median
”将查找其强度为所有给定图像的中值像素的像素。也就是说,对于每个位置,它都会收集并排序每个图像的像素强度。然后它将选择落在序列中间的像素。它也可以用作简单地对图像集合的像素进行平均的替代方法。例如,可以通过将图像与两个上下“限制”图像结合使用来实现此目的。由于像素将是中间强度,因此您将获得原始图像的像素,或者“限制”图像的像素。换句话说,您可以使用它来“裁剪”原始图像的强度。奇怪但真实。对于偶数个图像,将选择更亮一侧的中间像素。因此,对于只有两个图像,此运算符将等效于逐像素“按强度亮化”。关键是每个像素完全来自一个图像,并按强度排序。每个像素的确切颜色完全来自给定图像中的一个,因此不会生成新的颜色。例如,以下是使用玫瑰图像的所有 翻转和翻转 版本计算的中值强度的像素。请注意,它不像以前那么平滑,但可能会获得清晰的边界,因为它基于像素的强度。
|
![]() |
添加多个图像
“Add
”方法当然会简单地将所有图像加在一起。
magick ... -evaluate-sequence add ... |
magick ... -background black -compose plus -layers flatten ... |
减去多个图像
“Subtract
”方法从第一个图像中减去每个图像。或者至少它应该这样做。在内部,它的参数已交换,它从下一个图像中减去先前的结果。啊!但是通过利用 线性燃烧合成方法 的一个特性,您可以从第一个图像中减去第二个及后续图像。基本上通过 反转 除第一个图像之外的所有图像,并将“white
”(反转的零)设置为起始背景颜色,然后您可以使用 Flatten 将所有图像从第一个图像中减去。
magick ... \ -negate \( -clone 0 -negate \) -swap 0 +delete \ -compose LinearBurn -background white -flatten \ ... |
乘/除多个图像
“Multiply”和“Divide”被“-evaluate-sequence
”接受为方法,但它们会生成意外和奇怪的结果,因为它们使用的是图像的实际颜色值而不是规范化的颜色值,就像“-evaluate
”一样。结果,乘法和除法的比例过大。这可以归类为错误。同时,您最好使用 Multiply 的等效“flatten”方法,该方法按预期工作。
magick ... -background white -compose multiply -layers flatten ... |
Poly - 使用多项式合并多个图像
与“-evaluate-sequence
”密切相关,特别是与“mean”方法(图像平均)相关的是“-poly
”运算符(在 IM v6.8.0-5 中添加)。此运算符为内存中的每个图像提供两个数字的列表,一个用于为每个图像提供乘法权重,另一个用于为每个图像提供幂指数。这允许您将图像列表合并,就像每个图像都是多项式方程的变量输入一样。每个图像的颜色值都被视为 0 到 1 的归一化值。对于每一对值,图像颜色(归一化)首先由第二个“幂”指数进行幂运算,然后由第一个数字进行加权(乘法)。如果指数为“1
”,则该值仅乘以给定的权重。但是,如果指数为“0
”,则权重将成为最终值,产生归一化的颜色常量加法(值从 0.0 到 1.0)。可以在当前图像序列中提供单个像素图像,并用于添加特定颜色,每个通道具有不同的归一化颜色值。(使用权重和指数 = 1.0)。或者您可以提供“NULL:
”图像(或任何其他垃圾图像),并使用 0.0 的指数。这只会将给定的加权因子添加为常量。最终图像由第一个图像(及其大小和其他元数据)生成,就像 FX DIY 运算符 一样。例如...
|
![]() |
rose:
”(使用权重 1 和幂 1 未修改),在此基础上添加“granite:
”图像的两倍颜色值(权重=2),最后使用“null:
”图像减去值 1,使用指数 0(忽略图像输入)和权重值 -1.0。生成的图像等效于...rose + 2.0*granite - 1.0
rose + 2.0*(granite-0.5)
亮光
”合成照明效果完全相同,但对花岗岩叠加层进行了非常明确的权重设置。与其他多图像操作相比,关键的区别在于能够单独为每个图像加权,但在单个图像处理操作中执行所有计算,而无需额外的中间图像。这避免了在 ImagMagick 的非HDRI 版本中对最终结果的任何量子舍入、裁剪或其他影响。(参见量子效应)。例如,它可以用于执行大量图像的加权平均,例如对较小的图像组进行平均,然后对这些组进行平均。