ImageMagick 示例 -- 图像合成
- 定义与术语
-
Over、Dst Over、Src、Copy、
Dst、In、Dst In、Out、Dst Out、
ATop、Dst ATop、Clear、Xor -
Multiply、Screen、Bumpmap、Divide、
Plus、Minus、ModulusAdd、ModulusSubtract、
Difference、Exclusion、Lighten、Darken、
LightenIntensity、DarkenIntensity、 - 集合论等价运算
- 数学合成与 Alpha 混合
- 使用图像合成进行图像通道数学运算
-
Overlay、Hard Light、Soft Light、Pegtop Light、
Linear Light、Vivid Light、Pin Light、
Linear Dodge、Linear Burn、Color Dodge、Color Burn、 -
Copy Opacity、Copy Red、Copy Green、Copy Blue、
Copy Cyan、Copy Magenta、Copy Yellow、Copy Black、
Hue、Saturate、Luminize、Colorize、 -
Mathematics、Change Mask图像映射合成方法可变
Blur、Displace映射 图像合成是将带有或不带有透明度(alpha 通道)的图像组合在一起的技术。这通常通过 IM 的“magick composite”命令来完成。它也可以作为一系列更大操作的一部分,或由其他图像操作符在内部执行。
IM 中的图像合成
图像合成是将两幅(且仅两幅)图像以多种方式合并的过程。它与 alpha 合成密切相关,后者根据叠加图像哪一部分是透明的来描述结果。图像合成可用于混合和平均图像、传递图像通道、剪切、拼接或分层排列形状不规则的图像片段,也可作为复杂数学运算的一部分。关于图像合成的另一份不错的入门介绍是 30分钟了解SVG合成。你也可以阅读 SVG Alpha 合成 页面来了解精确的数学细节,该页面描述了更重要的图像合成方法。以下命令是 ImageMagick 中可直接使用的两种图像“合成”方法……
magick composite {_overlay_} {_background_} [{_mask_}] [-compose {_method_}] {_result_}
magick {_background_} {_overlay_} [{_mask_}] [-compose {_method_}] -composite {_result_}
“magick composite”命令是 IM 中传统的合成方式。拥有一个专门的命令说明了图像合成有多么重要。“magick”操作符“[-composite](https://imagemagick.org/command-line-options/#composite)”也可以在更大的图像处理任务中完成图像合成。</> 请注意,使用“magick”时图像的顺序是相反的。这种顺序是符合实际的,因为你通常是在一个主画布上准备并合并图像,从而形成一幅新图像。图像的顺序很重要。这两种技术(以及更多内容)的实际示例可以在 多图层 中查看,建议在继续之前先阅读。
定义与术语
其中更重要的图像是_背景_图像,也常被称为_目标_图像,它是被图像合成所修改的图像。背景_不仅决定了图像合成的最终尺寸,还会保留诸如“注释”“标签”“密度”“配置文件”等_元数据。它的位置是固定的,通常构成你正在搭建的画布,因此得名_背景_。请牢记这一点!
_叠加_图像,或称_源_图像,控制着“[-compose](https://imagemagick.org/command-line-options/#compose)”方法应如何修改固定的_背景_或_目标_图像。该图像可以相对于固定的_背景_图像重新定位(通常使用“[-geometry](https://imagemagick.org/command-line-options/#geometry)”和“[-gravity](https://imagemagick.org/command-line-options/#gravity)”设置)。然而,_叠加_图像本身以及它所包含的任何元数据,在合成操作完成后都会被删除。
有时命令中会加入第三张_蒙版_图像。该图像用于定义和控制_背景_图像的哪些部分会被最终合成结果修改,以及修改的程度。更多细节请参见下方的 合成蒙版。从 IM v6.5.3-4 起,特殊的 Define 设置“compose:outside-overlay”(参见 Outside-Overlay 设置)可以设为“false”,以禁止对_叠加_图像所覆盖矩形区域之外的_背景_图像做任何修改。如果不这样设置,某些合成_方法_会作为 compose 定义的一部分,清除未被_叠加_图像覆盖的区域。
实际的合成_方法_由“[-compose](https://imagemagick.org/command-line-options/#compose)”设置控制,默认值为“Over”。也就是说,源图像被绘制在_背景_图像之上,这正是大多数人在进行图像合成时脑海中所想的效果。IM Examples 的这一部分大多用于详细说明各种合成“方法”的作用以及如何使用它们。要查看各合成方法的效果,请参见 合成方法一览表。这些表格并不展示各方法的预期用途,只展示了针对各种测试图像的原始输出结果。合成方法名不区分大小写,且“_”或“-”字符是可选的。因此合成方法“Dst_Over”也可以写成“dst_over”“dst-over”“DstOver”“dstover”甚至“dstOVER”,它们的含义完全相同。另外,合成方法“Over”“ATop”“In”和“Out”分别是更冗长的合成方法名“Src_Over”“Src_ATop”“Src_In”和“Src_Out”的简写。在众多“[-compose](https://imagemagick.org/command-line-options/#compose)”方法中,有一些需要额外的数值参数才能正常工作。在“magick composite”命令中,这些参数通过特殊选项传递:“[-dissolve](https://imagemagick.org/command-line-options/#dissolve)”“[-blend](https://imagemagick.org/command-line-options/#blend)”“[-watermark](https://imagemagick.org/command-line-options/#watermark)”(“modulate”)“[-displace](https://imagemagick.org/command-line-options/#displace)”和“[-distort](https://imagemagick.org/command-line-options/#distort)”。从 IM v6.5.3-4 起,“magick”命令可以向“[-composite](https://imagemagick.org/command-line-options/#composite)”操作符传递特殊参数,方法是使用 Define 设置“compose:args”。相关示例请参见下方特殊的 Dissolve 和 Blend 方法。
图像合成操作符
除了上面展示的两图像直接合成方式外,还有一些其他图像操作在其内部图像处理过程中也用到了 alpha 合成。这些操作会受到当前“[-compose](https://imagemagick.org/command-line-options/#compose)”设置的影响,不过它们会使用各自内部的定位方式,或者使用 图层图像 的虚拟画布偏移定位技术。以下是已知会受 compose 设置影响的全部操作符列表……
图像对的合成 使用主要图像合成操作符的实际示例,既包括原始的“
magick composite”命令,也包括用于“magick”的“-composite”操作符。这种底层方法使用 几何/重心设置 来确定叠加图像的位置。 图层操作符 图像“层图像”操作符 "[flatten](layers.html#flatten)"、"[mosaic](layers.html#mosaic)" 和 "[-layers merge](layers.html#merge)" 会将当前图像序列中的所有多幅图像叠加到一张新画布上,画布的大小和位置由所选的图层操作符决定。这种方式使用 虚拟画布/页面偏移设置 来确定叠加图像的位置。 边缘扩展操作符 将每幅图像分别叠加到内部准备好的画布上的操作符。包括“[-border](https://imagemagick.org/command-line-options/#border)”“[-frame](https://imagemagick.org/command-line-options/#frame)”和“[-extent](https://imagemagick.org/command-line-options/#extent)”等操作符(参见 图像边缘的添加/移除)。这类操作不使用定位信息,不过“[-extent](https://imagemagick.org/command-line-options/#extent)”会利用重心和几何偏移,将图像叠加到纯色背景图像上。 绘制图像 “[-draw 'image...'](https://imagemagick.org/command-line-options/#draw)”图像叠加方法会将单张外部_源_图像叠加到一系列目标图像之上。这是 "[mogrify](basics.html#mogrify)" 唯一可用的图像合成技术。它从外部来源获取“叠加”图像,从而克服该命令不支持列表操作符的限制。用户还需提供缩放和定位信息,这些信息也可能受重心影响。 多列表图层合成 “[-layers composite](anim_mods.html#composite)”操作符可让你将两个独立的多图像列表逐对合成,从而形成一个新的合并多图像序列。它也可以将一个图像序列与单张图像(可以是静态的“叠加”图像,也可以是静态的“目标”图像)进行合成。它也是唯一一个允许你同时使用(全局的)受“[-gravity](https://imagemagick.org/command-line-options/#gravity)”影响的“[-geometry](https://imagemagick.org/command-line-options/#geometry)”偏移,以及各图像相对于该全局位置的虚拟画布“[-page](https://imagemagick.org/command-line-options/#page)”偏移的合成操作符。这个合成操作符对于整体合成 图像动画 或其他图像序列尤为重要,无需借助脚本逐对处理图像。
叠加图像的定位
合成的几何/重心设置
在普通的 alpha 合成中,“[-geometry](https://imagemagick.org/command-line-options/#geometry)”设置与“[-gravity](https://imagemagick.org/command-line-options/#gravity)”一起使用,用于将源图像相对于目标图像定位。这些设置的使用方法在 使用重心进行图像定位 中有详细介绍。请注意,“[-geometry](https://imagemagick.org/command-line-options/#geometry)”中的尺寸部分比较特殊,因为它会 调整图像大小(geometry)。在 "[composite](../static/img/compose/composite)" 中它会调整源图像的大小,而在 "[convert](../static/img/compose/magick)" 中则会调整图像序列中最后一张图像的大小。严格来说,这属于 图像合成 之外的另一个方面。参见 几何缩放 和 使用合成分层图像。在 alpha 合成中只涉及两幅图像,即“源”图像和“目标”(或“背景”)图像,不过也可以提供第三张 蒙版图像 来限制合成所影响的区域。
图层画布/页面偏移
分层图像的合成采用了截然不同的理念。所有图像(数量不限)都按给定顺序被平等对待。它们都拥有一个“[-page](https://imagemagick.org/command-line-options/#page)”即 页面偏移,用于将每幅图像的左上角相对于虚拟画布的“原点”(默认偏移)定位,但不受重心影响。在处理多幅图像时,会使用当前的“[-background](https://imagemagick.org/command-line-options/#background)”颜色生成一张新的背景图像,其大小取决于所执行的操作。这张图像被视为“目标”图像(画布)。所有图像都会依次逐一合成到这张新画布上。即使只给出两幅图像,仍会创建一张新图像,并应用两次独立的合成操作,也就是说速度会比较慢。所有图像都被视为“源”图像,其列出的顺序决定了最终结果。不过“图层”偏移不受重心影响。由于每幅图像都可以有各自独立的“画布偏移”,多图像合成最好使用 图像图层操作符,以及针对动画的 多图像序列合成 来实现。这两种定位方式截然不同,务必针对你打算使用的合成技术选用正确的方式。
两种定位技术并用
只有一种合成技术——多图像列表 图层合成 操作符——允许你同时使用两种定位方式。首先,两个列表会使用“[-geometry](https://imagemagick.org/command-line-options/#geometry)”和“[-gravity](https://imagemagick.org/command-line-options/#gravity)”进行全局定位,作用于各列表中第一幅图像的虚拟画布尺寸。然后,列表中的每幅图像再基于该全局位置,使用“[-page](https://imagemagick.org/command-line-options/#page)”进行偏移,从而确定最终位置。当然,如果所提供的叠加图像无法完全放入某张特定的目标图像中,它就会被该图像裁剪。因此,通常最好只对目标图像使用已完全合并(fully-coalesced)且尺寸合适的图像。之后当然也可以再对生成的图像进行裁剪调整。
Duff-Porter Alpha 合成方法
Duff-Porter 图像合成方法是一套传统的、定义非常严谨的 12 种方法。之所以称为 Alpha 合成,是因为图像是根据图像透明度即“Alpha 通道”的某些方面进行合并的。你可以在 SVG Alpha 合成 文档中找到这些方法的数学定义。下面是一张经典表格,展示了用两幅三角形图像应用这 12 种方法的结果。
另请参见 合成方法原始表格,其中用不同形状和渐变的图像图示展示了更多合成方法。默认的合成方法(完全未指定时)是“Over”,这也是大多数人在合成图像时通常想要的效果。为了理解并记住上述每种合成方法的作用,可以把最终结果想象成如下表达式的结果……
**{_Source_} --{_compose_method_}--> {_background_}**
****
也就是说,方法“ATop”的合成结果,相当于“叠加图像‘ATop’于背景图像”。也就是说,背景图像会保持其“形状”,但源图像的颜色会“覆盖在”背景之上。不过请记住,使用“[magick -composite](https://imagemagick.org/command-line-options/#composite)”操作符时图像顺序是相反的。这 12 种方法不仅决定了两幅图像中哪一幅在结果中“可见”,还决定了它对未被_源_图像叠加的部分会产生怎样的影响,也就是原始的“背景”是保持原样,还是被完全清除。我特意让上表中的“目标”图像大一些,以便你能看出图像其余部分是否被清除。这些“清除型”方法包括:“[Src](#src)”“In”“[Dst_In](#dstin)”“Out”“Dst_ATop”以及“[Clear](#clear)”。从 IM v6.5.3-4 起,你可以使用 Define 设置“compose:outside-overlay=false”来防止 Duff-Porter 合成清除_叠加_区域之外的_目标_图像。相关示例请参见“[Copy](#copy)”和“[Clear](#clear)”合成方法,以及 Outside-Overlay 设置 的详细说明。请注意,“[Copy](#copy)”是 IM 提供的一种特殊的“第13种”合成方法。基本上它等同于“[Over](#over)”合成,但会清除叠加区域内的背景。不过从实现角度来说,它其实是禁用了叠加区域外背景清除(compose:outside-overlay=false)的“[Src](#src)”合成。 |
ImageMagick v5 及更早版本不会清除任何未被源图像叠加的区域。这是 Duff-Porter 合成操作符的一种错误处理方式,已在 IM v6 的开发过程中得到修正。 |
|---|---|
Duff-Porter Alpha 合成方法最重要的特性之一,就是它们绝不会让“完全透明的彩色像素”变为可见。这一点很重要,因为图像中完全透明的部分颜色是未定义的——它实际上可以包含任意颜色值,而不会影响图像的可见结果。有关“处理透明通道”的详细信息,请参见 控制图像透明度。这也是为什么 Duff-Porter 合成通常是首选的蒙版方法,而不是会完全替换图像 Alpha 通道、并可能使那些未定义的不可见颜色变为可见的“[CopyOpacity](#copyopacity)”方法。 |
Over(叠加图像置于背景之上)
这是默认的合成方法,也是大家在把一幅图像叠加到另一幅图像上时最先想到的方法。叠加图像被放置在背景图像“之上”,就像把“动画赛璐珞片”或“投影胶片”放在背景场景或图像上方一样。这种方法太常见了,我想应该不需要再多做说明。那么让我们来看一个把单个字母图像叠加到背景图像上的示例。 |
magick -background none -fill white \
-font Ravie -pointsize 36 label:A label_A_white.png
magick composite -gravity center label_A_white.png rose: compose_over.gif
![[IM Output]](../static/img/compose/label_A_white.png)
![[IM Output]](../static/img/compose/compose_over.gif)
叠加图像可以像上面那样用 gravity 居中,也可以使用精确的 "[-geometry](https://imagemagick.org/command-line-options/#geometry)" 设置来定位。如果它被定位在背景边界之外,超出部分会被裁剪或忽略,视情况而定。在这个例子中,图像使用 "convert -composite" 操作符进行叠加,但被定位在背景上方一半的位置。注意图像顺序的反转。 |
magick rose: label_A_white.png \
-geometry +5-15 -composite convert_over.gif
Dst_Over(将图像放在背景'之下')
和其他 'Dst_' 方法一样,这个方法的工作方式几乎与该方法的 'Src_' 版本完全相同,只是叠加图像和背景图像互换了。因此 '[Dst_Over](#dstover)' 相当于把源叠加图像放置在目标图像的'下方'。结果是只有那些没有被目标或背景图像遮挡的源图像或叠加图像部分,才会作为从下方露出的部分可见。这与简单地交换参数图像后使用 '[Over](#over)' 并不完全相同,因为图像尺寸、定位以及其他图像元数据仍然来自背景或目标图像。请记住,输出图像的尺寸与'背景'图像相同,源图像的位置是相对于背景而言的(使用 "[-geometry](https://imagemagick.org/command-line-options/#geometry)" 和 "[-gravity](https://imagemagick.org/command-line-options/#gravity)")。例如,这里我们把一个黑色的 'A' 标签叠加在原始的白色 A '下方'。我们可以相对于白色 A 背景重新定位黑色 A。如你所见,这非常适合用来添加硬阴影,而无需担心需要扩大图像尺寸。 |
magick -background none -fill black \
-font Ravie -pointsize 36 label:A label_A_black.png
magick composite -compose Dst_Over -geometry +5+5 \
label_A_black.png label_A_white.png compose_under.png
![[IM Output]](../static/img/compose/label_A_black.png)
![[IM Output]](../static/img/compose/compose_under.png)
需要注意的重点是,背景的尺寸得以保留,而叠加图像相对于背景的位置可以修改,并且会被背景裁剪。这正是使这个操作符如此重要和有用的原因。"[-tile](https://imagemagick.org/command-line-options/#tile)" 设置在 "magick composite" 中,也使这种形式的 'over' 在图像下方平铺时非常有用。例如,把内置的棋盘格图案平铺在我们刚创建的带阴影字母的下方。 |
magick composite -compose Dst_Over -tile pattern:checkerboard \
compose_under.png compose_under_tiled.jpg
Src('裁剪'为背景图像的尺寸)
这个操作符会完全用叠加图像替换背景图像。背景中的颜色和透明度被完全丢弃,留下一张与原始目标图像尺寸相同的空白图像,在其上应用源图像。但这有什么用呢?其实有两点好处。首先,你实际上是用源图像替换了背景图像,但保留了与原始背景图像相关联的所有元数据。也就是说,图像内容改变了,但元数据没有改变。其次,最终图像的尺寸不会改变,即使图像内容发生了变化。也就是说,结果图像的尺寸与原始背景相同。因此,你可以有效地使用这个操作符来裁剪源图像或叠加图像,或者为其添加边框,使其变为与给定背景图像相同的尺寸(连同背景的元数据)。例如,假设你想制作一张 plasma 图像,并将其裁剪为与内置 rose 图像相同的尺寸。这样你就不需要知道 rose 图像到底有多大就能做到这一点。 |
magick composite -compose Src -size 100x100 plasma:tomato-dodgerblue \
rose: compose_crop.gif
![[IM Output]](../static/img/compose/compose_crop.gif)
当然,上面的效果相当于对 plasma 图像进行 "[-crop](https://imagemagick.org/command-line-options/#crop)",而不是 'resize'。原始图像的元数据也得以保留。也就是说,尽管现在这是一张 plasma 图像,图像元数据仍然显示它是一张 'rose' 图像,并且来自 "rose:" 图像源。
如果叠加图像比较小,背景图像其余的部分会被透明填充。但请注意,背景必须具有 alpha 通道,否则多出的空间会用黑色填充(这是 'none' 或 'transparent' 在没有 alpha 通道时所呈现的颜色)。 |
magick composite -compose Src -gravity South \
hand_point.gif rose: -alpha set compose_expand.gif
Copy(复制或替换图像)
这个操作符不属于上表所列的 12 种 'Duff-Porter' 合成方法之一,这就是它没有出现在上面图表中的原因。尽管如此,它仍然非常重要。它的工作方式与 "Src" 合成方法完全相同,但它不会触及叠加区域之外的背景图像。也就是说,它把复制能力限制在被叠加的区域内,不涉及其他任何部分。这使你能够裁剪出较大图像中的一小部分,为了速度在这张较小的图像上进行处理,然后将结果'复制'回较大的图像上,而不触及该图像的其他区域。这反过来使你能够优化对超大图像的处理。这里是我上面用过的同一个例子,但改用 '[Copy](#copy)' 而不是 '[Src](#src)',展示了 IM 不会像 'Duff-Porter' 算法所要求的那样浪费时间去清除背景的其余部分。 |
magick composite -compose Copy -gravity South \
hand_point.gif rose: -alpha set compose_copy.gif
![[IM 输出]](../static/img/compose/compose_copy.gif)
这个运算符与"[Over](#over)"也非常相似,不同之处在于源图像的透明度也会被复制,完全替换背景图像。如果没有透明度,其效果与"[Over](#over)"完全一致。它在内部会修改特殊合成控制设置"outside-overlay"(见下文)。
Outside-Overlay 设置
自 IM v6.5.3-4 起,通过定义 "compose:outside-overlay",用户可以控制合成方法是否也会影响叠加区域之外的区域。默认为"开启",但可以将其值设为"false"来关闭。例如,下面这个示例等价于Copy 合成方法,但使用了更传统的Src 合成方法…… |
magick rose: hand_point.gif -alpha set -gravity South \
-define compose:outside-overlay=false \
-compose Src -composite compose_copy_src.gif
![[IM 输出]](../static/img/compose/compose_copy_src.gif)
有关使用此标志的示例,请参见PageCurl 角落叠加。
Outside-Overlay 与 SVG 'clip-to-self' 的比较
"compose:outside-overlay"定义在许多方面类似于使用 SVG 的'clip-to-self'属性。两者都将合成限制在被叠加的区域内,而不影响目标图像的其余部分。然而,SVG 的'clip-to-self'只作用于已绘制的区域(类似蒙版),而 IM 的'outside-overlay'设置则作用于源图像叠加背景图像时所占据的完整矩形区域。SVG 合成手册对此说明不够清楚,所给的示例解释得也不好,容易让人困惑。但如果你想尝试理解,可以参见SVG Composition 'clip-to-self' property或Understanding SVG 1.2 composition, clip-to-self。需要注意的是,写入蒙版也可以实现这种控制方式,但会根据所给蒙版的形状来限定区域。从这个角度看,它更接近 SVG 的'clip-to-self'属性,因为源图像本身也被用作写入蒙版。
Dst(一个"无操作"合成)
此运算符不执行任何操作。源图像(即叠加图像)会被完全忽略,目标图像(即背景图像)保持不变。这个方法的真正用途是在其他图像运算符中"关闭" alpha 合成操作。例如,我们使用Frame 运算符为玫瑰图像(带透明背景)添加边框,然后使用"-compose Dst"来阻止该图像被添加到边框中。换句话说,我们仅使用玫瑰图像来设定结果内部边框的大小。最终结果只有边框本身。 |
magick rose: -alpha set -mattecolor Gold -bordercolor none \
-compose Dst -frame 7x7+3+2 compose_frame_dst.gif
![[IM 输出]](../static/img/compose/compose_frame_dst.gif)
特殊的Alpha Set操作可确保图像中存在Alpha 通道,否则你最终得到的会是黑色的中间区域而不是透明的。"[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)"用于定义边框内部的颜色,该颜色通常位于源图像下方。'[Dst](#dst)'方法在脚本中也很有用,可以在一个庞大而复杂的命令中禁用 alpha 合成,而无需创建两条不同的 IM 命令。
Dst_In(即用源图像给背景加蒙版)
'**Dst_In**'方法相当于将源图像用作背景图像的'Copy_Opacity'蒙版。它会像饼干模具一样,从背景图像中裁切掉叠加图像的形状,就像用模具从面团上切出饼干形状一样。例如,让我们用上面那个花式字母'A'作为蒙版,从玫瑰图像上裁切出它的形状。 |
magick composite -compose Dst_In -gravity center \
label_A_white.png rose: -alpha Set compose_mask.png
![[IM 输出]](../static/img/compose/compose_mask.png)
与'[Copy_Opacity](#copyopacity)'方法不同,此操作中不能使用灰度图像作为蒙版,因为该操作仅使用叠加图像的 alpha 通道,叠加图像中的任何颜色都会被完全忽略。 | 'Dst_In'和'Src_In'方法实际所做的,就是将两幅图像的 alpha 通道相乘。相应图像(根据方法而定)的颜色则会被保留。
---|---
Dst_Out(即"擦除"操作)
沿用'[Dst_In](#dstin)'的"饼干面团"比喻,'**Dst_Out**'方法的结果就是切出饼干形状后剩下的那部分面团。它可以用来在背景图像上按叠加图像的形状打洞,或者"咬"出一块缺口。叠加图像中的任何颜色同样会被完全忽略。 |
magick composite -compose Dst_Out -gravity center \
label_A_white.png rose: -alpha Set compose_erase.png
![[IM 输出]](../static/img/compose/compose_erase.png)
这两种合成方法的数学公式经过精心设计,使得如果你对同一组图像使用'[Dst_In](#dstin)'和'[Dst_Out](#dstout)',就可以(使用'[Plus](#plus)'方法)把它们重新拼合起来,就像拼图一样。例如,这里我们(使用'[Plus](#plus)'合成)将上面生成的最后两张图像"相加"。这张图像与原始的'rose:'图像完全相同(精确到每个像素)。 |
magick composite -compose Plus compose_mask.png compose_erase.png \
compose_rejoin.png
![[IM 输出]](../static/img/compose/compose_rejoin.png)
在任何图形软件中,擦除图像的一部分都不是一件容易的事。例如,"[-draw](https://imagemagick.org/command-line-options/#draw)"操作只能向图像添加颜色,一旦颜色被应用到画布上,它就无法将其移除。可以想象一位画家正在玻璃门或窗户上绘制广告:他(或她)可以添加颜料,但无法通过在颜料上覆盖来将其去除。通过将想要擦除的形状绘制到透明画布上,你就可以使用'[Dst_Out](#dstout)'将其从工作图像中移除。这有点像画家用一块特制形状的抹布小心地擦掉未干的颜料。这个形状可以用来完全或部分地移除颜色,使其变为完全透明或半透明。例如,假设你想在透明画布上绘制一个新月符号,通过叠加两个圆形,这种 alpha 合成方法可以让这个原本很难绘制的形状变得容易实现。 |
magick -size 70x70 xc:none -fill white -draw 'circle 35,35 35,5' \
\( -size 70x70 xc:none -fill black -draw 'circle 28,30 35,5' \) \
-alpha Set -compose Dst_Out -composite moon_crescent.png
![[IM 输出]](../static/img/compose/moon_crescent.png)
| 第二张图像必须在括号内创建并绘制。如果不这样做,你会发现"[-draw](https://imagemagick.org/command-line-options/#draw)"会同时绘制到叠加图像和原始背景图像上,这显然是错误的。 如果不使用括号,你会发现在图像被擦除部分的周围出现一圈半透明的黑色像素。没错,我在制作这个示例时就亲身遇到过,让我相当懊恼。
---|---
ATop(类似"Over",但裁剪到背景图像)
类似于"[Over](#over)",但将结果限制在背景图像的原始形状范围内。换句话说,目标图像的 alpha 通道保持不变,但源图像中任何非透明部分都会叠加到目标图像的颜色上。如果背景图像完全不透明(没有透明区域),此操作的效果将与普通的"[Over](#over)"合成完全相同。只有当背景包含透明区域、从而也会裁剪叠加图像时,两者才会有差异。这个特性的用处在于叠加仅限于目标对象(形状)范围内的光照和阴影效果。例如,假设我们有一个红色圆形,想要为它添加高光,使其看起来像一个三维的球体。我们可以先创建圆形和高光,然后使用"[ATop](#atop)"叠加高光,将其限制在圆形范围内。 |
magick -size 70x70 xc:none \
-fill red -draw 'circle 35,35 10,30' red_circle.png
magick -size 70x70 xc:none -draw 'circle 35,35 35,20' \
-negate -channel A -blur 0x8 red_highlight.png
magick composite -compose ATop -geometry -13-17 red_highlight.png \
red_circle.png red_ball.png
![[IM Output]](../static/img/compose/red_ball.png)
创建白色高光时使用了"-negate",以确保整个图像确实为白色。这样做是为了避开"-blur"运算符中的一个bug,该bug已在IM 6.2.4版本中修复。有关这个旧bug的更多细节,请参见模糊与透明度Bug。
---|---
以类似的方式,我们可以为球体添加一个模糊的阴影,并将其裁剪到球体本身的边界内,这样球体看起来会更加立体。至于以下命令是如何实现这一效果的,就留给读者自己去研究了。 |
magick moon_crescent.png -fx 0 -channel A -blur 0x7 \
red_ball.png +swap -compose ATop -composite red_ball2.png
![[IM Output]](../static/img/compose/red_ball2.png)
如果在准备图像时再多花些心思,上面的图像可以做得更加逼真。就演示这种合成方法的用法而言,这个效果已经不错了。有关"[ATop](#atop)"合成方法的更多使用示例,请参见生成3D徽标。
Clear(清除背景,忽略叠加图像)
这是一种不常见的合成方法,它基本上完全忽略叠加图像,只是清除背景图像。这使得它成为为复杂项目创建与背景图像大小相同的透明或黑色画布的理想方法。由于不会用到叠加图像,使用单像素的"null:"图像作为叠加图像是个不错的选择。 |
magick composite -compose Clear null: rose: -alpha Set compose_clear.png
![[IM Output]](../static/img/compose/compose_clear.png)
当然,Alpha Set操作(虽然在这种情况下并非必需)可以确保目标图像具有alpha 通道,以便在将图像清除为透明时使用。如果你专门关闭了alpha 通道,由于所涉及的运算方式,该运算符会将图像清除为黑色。 |
magick composite -compose Clear null: rose: -alpha Off compose_black.png
![[IM Output]](../static/img/compose/compose_black.png)
特殊的定义设置"compose:outside-overlay"允许你将这种清除操作限制在被叠加的区域内,而不论叠加图像是否包含透明部分。例如: |
magick rose: hand_point.gif -alpha Set -gravity South \
-define compose:outside-overlay=false \
-compose Clear -composite compose_clear_limited.gif
Xor(清除共享区域)
这是一种非常奇特且很少使用的合成方法。它先叠加两张图像,然后将重叠区域清除为透明。 |
magick -size 60x60 \
\( xc:none -fill blue -draw 'circle 21,39 24,57' \) \
\( xc:none -fill red -draw 'circle 39,39 36,57' \) \
-compose Xor -composite compose_xor_2.png
![[IM Output]](../static/img/compose/compose_xor_2.png)
当对上述结果再进行一次异或运算,叠加第三张图像时,情况就变得更加有趣了。 |
magick -size 60x60 compose_xor_2.png \
\( xc:none -fill green -draw 'circle 30,21 30,3' \) \
-compose Xor -composite compose_xor_3.png
![[IM Output]](../static/img/compose/compose_xor_3.png)
如你所见,多张图像重叠可以产生一些奇妙的效果:任意偶数张图像重叠的区域会变为透明,而任意奇数张图像重叠的区域则会显示出最上层图像。
FUTURE: Xor effects on semi-transparent images get extremely weird.
Explore this and create an example demonstrating this weirdness.
数学合成方法
这一组合成方法让你可以对图像进行数学运算。这看起来似乎没什么用,但对于图像的底层处理来说,这些方法能让你做一些平常想不到的事情。与前面的 Duff-Porter 图像合成方法不同,它们通常是灰度方法。也就是说,它们通常被应用于其中一幅或两幅图像都是灰度图的情况,并且通常不包含透明度。这并不是说不能使用透明度(见下文的 数学合成与 Alpha),只是这种做法并不常见。数学合成的默认行为由 SVG 图像文件格式规范定义。你可以在 SVG Composition Guide (2009) 中了解更多,也可以参阅 Pegtop Blend Modes 和 SimpelFilter: Photoshop Blend Modes。下面每种运算符旁边的特殊渐变图像展示了该运算符如何影响颜色值。这个结果是通过如下方式合成两张渐变图像得到的……
magick -size 64x64 gradient: gradient_src.png
magick -size 64x64 gradient: -rotate 90 gradient_dst.png
magick composite gradient_src.png -compose Multiply gradient_dst.png \
gradient_result.png
![[IM Output]](../static/img/compose/gradient_src.png)
源图像 | | ![[IM Output]](../static/img/compose/gradient_dst.png)
目标图像 | | ![[IM Output]](../static/img/compose/gradient_result.png)
结果
---|---|---|---|---
基本上,如果你把叠加图像(源图像)的颜色值作为纵轴,背景图像(目标图像)的颜色值作为横轴,你就可以查到应用该运算符后得到的结果值。在上面的例子中,你会看到 '[Multiply](#multiply)' 通常会使图像变暗,并且任意一幅输入图像中的黑色值(0)都会导致结果为黑色。这个特性有时非常有用。 ![[IM Output]](../static/img/compose/gradient_op_multiply.png)
Multiply(乘法)(用于把白色变为透明,适合图表/文字)
这是较为实用但常被低估的合成方法之一,它是对两幅图像进行简单的相乘运算。它的公式当然就是:_Src_ *_Dest_ 这意味着,如果其中一幅图像是纯白色,结果就会是另一幅图像。反之,如果一幅图像是黑色,结果就会是黑色。在这两个极端之间,一幅图像会按给定的量使目标图像变暗。请注意,'Multiply' 只会使图像变暗,绝不会使其变亮。也就是说,它会将图像“衰减”至黑色,这使得该合成方法属于一种 'Burn(加深)' 风格的合成方式。(参见下文的 光照合成方法) |
magick label:Rose label_white.gif
magick composite -compose Multiply -gravity center \
label_white.gif rose: compose_multiply.gif
![[IM Output]](../static/img/compose/label_white.gif)
![[IM Output]](../static/img/compose/compose_multiply.gif)
这种方法在很多情况下都非常好用,尤其适合当其中一幅图像在大部分为白色的背景上带有黑色(或灰度)线条时,例如文字图像。如果两幅图像都包含有色区域,那么你可能会得到不寻常的结果。换句话说,这种技术非常适合将图像及其他图表直接叠加到带有白色或浅色背景的线条画上。举例来说,我想在一幅将要用于光线追踪图像的文字页面上添加一些图表。你可以在我的 Studies in Polyhedra 结果图像中看到这个“文字页面”。给定两幅灰度图像蒙版,Multiply 也是一种基于某个蒙版将图像局部擦除为黑色的好方法。它是以线性方式进行的,因此蒙版可以是灰度图像,而不必是纯粹的布尔开/关图像。参见 数学合成。将一幅图像与自身相乘实际上是一种实用的技术,可以对图像进行平方式的变暗处理,使明亮的颜色依然突出,而其他颜色则变得更暗。实际上,这等价于取值为 "0.5" 的 Gamma 运算符,或者取值为 "2.0" 的 Evaluate PowerOf 运算。举例来说,可以参见 Star Generator,用于生成更真实的星光亮度分布。它也可以用于卫星云图,在将结果叠加到地理地图之前进行处理。 ![[IM Output]](../static/img/compose/gradient_op_screen.png)
Screen(滤色)(用于把黑色变为透明,适合图表/文字)
这几乎和 '[Multiply](#multiply)' 完全一样,只是在合成之前先对两幅输入图像取反,最终结果也再次取反以恢复图像的正常状态。从技术上讲,这两种方法互为“对偶”。这使得它的公式为:1-(1-_Src_)*(1-_Dest_) 这意味着,如果其中一幅图像是纯黑色,结果就会是另一幅图像。反之,如果一幅图像是白色,结果就会是白色。在这两个极端之间,一幅图像会按给定的量使目标图像变亮。请注意,'Screen' 合成只会使图像变亮,绝不会使其变暗。这是一种被称为 'Dodge(减淡)' 的合成风格。(参见下文的 光照合成方法)这种合成方法非常适合把白色文字叠加到黑色背景上,然后再叠加到其他图像上…… |
magick -background black -fill white label:Rose label_black.gif
magick composite -compose Screen -gravity center \
label_black.gif rose: compose_screen.gif
![[IM Output]](../static/img/compose/label_black.gif)
![[IM Output]](../static/img/compose/compose_screen.gif)
关于如何利用这种方法将白色形状叠加到图像上的示例,请参见 数学蒙版。 ![[IM Output]](../static/img/compose/gradient_op_bumpmap.png)
Bumpmap(灰度乘法)
'[Bumpmap](#bumpmap)' 方法本质上和 '[Multiply](#multiply)' 相同,区别在于源图像在叠加之前会先被转换为灰度图。换句话说,只要源图像较暗的地方,它就会使图像变暗。你可以把它理解为一种“按亮度相乘”的运算符。举例来说…… |
magick composite -compose Bumpmap -gravity SouthEast -geometry +3+3 \
hand_point.gif cyclops.gif -alpha Set compose_bumpmap.gif
![[IM Output]](../static/img/compose/compose_bumpmap.gif)
注意 "hand_point.gif" 图像在应用前是如何被灰度化的。它最初的用途是为图像添加纹理(例如纸张或织物的质感)。不过,由于它只能使图像变暗,所以不如 '[HardLight](#hardlight)' 方法实用,后者既能使图像变亮,也能使图像变暗(见下文)。 ![[IM Output]](../static/img/compose/gradient_op_divide.png)
Divide、Divide_Dst、Divide_Src ( )(去除阴影效果)
两幅图像相互相除。哪幅图像除以哪幅图像取决于应用的是“Divide_Src”还是“Divide_Dst”。“Divide_Dst”的公式为 _Src_ / _Dest_,“Divide_Src”的公式为 _Dest_ / _Src_。由于图像合成及“magick composite”命令中通常定义的图像顺序,原始方法“Divide”的含义是……
**{_Source_} Divide {_background_}**
****
也就是说,原始方法名“Divide”是“Divide_Dst”(意为“除以目标”)的同义词。它也是用于定义所显示的渐变图表的运算符。请注意图像的顺序非常重要,因为如果交换图像或运算符,会得到截然不同的结果。在使用“magick”命令时尤其如此,因为该命令是目标图像在前、源图像在后。请记住,是目标图像决定了两幅图像合成结果的最终尺寸和元数据。同样要记住,是源图像相对于目标图像来定位的。这种合成方法在从照片中去除渐晕方面用途最广。在下一个示例中,我将用它来去除背景。
由于使用的是归一化的颜色值,其范围通常为 0.0(黑色)到 1.0(白色),因此相除实际上会使分子图像变亮,变亮的程度取决于“被除”图像中出现的“黑色”量。既然是两幅图像相除,那么“分子”图像(即未被运算符指定的那一幅)会变亮,这听起来可能有点奇怪。但这其实是一个非常有用的操作。这意味着你可以有效地去除由镜头渐晕、扫描不良或年代造成的变色所引起的图像暗斑。例如,我有一张手写文字的图像,它的扫描非常粗糙(使用数码相机、不开闪光灯拍摄,然后缩小尺寸以去除数字噪点)。纸张边缘褪色,而且由于没有使用闪光灯,背景非常暗,并且由于纸张不完全平整而产生了阴影效果。
仅仅通过归一化来增强图像对比度,并不能去除边缘变色或其他阴影效果。
magick text_scan.png -normalize text_scan_norm.png
然而,通过模糊图像以去除线条,再用原图除以该模糊图像,我们就能有效去除图像中所有严重的阴影效果。
magick text_scan.png \( +clone -blur 0x20 \) \
-compose Divide_Src -composite text_scan_divide.png
相除的结果是背景颜色变为白色,而文字的细线则保持清晰,只是略微“变细”了一点。可以看到,这比单纯归一化清晰得多,尽管也去除了一些抗锯齿效果。原本还可以对除数图像做一些额外调整,但目前的结果已经非常接近预期了。使用更小的模糊半径可以产生另一种生成艺术风格轮廓图像的方法,如给轮廓图像上色中所示。此运算符还可以与背景渐变生成器(如稀疏颜色渐变)结合使用,以生成比单纯模糊整幅图像更好的背景“除数”图像。
这两个相除运算符实际上与“[Color_Dodge](#colordodge)”合成方法类似,只是除数图像被取反后用作源图像。这正是 Photoshop 中通常使用的合成方式,不过你可能需要交换并取反图像。相关等价关系请参见“[Color_Dodge](#colordodge)”。 | 在 IM v6.6.8-5 之前,只提供原始的“[Divide](#divide)”方法(相当于较新的“[Divide_Dst](#dividedst)”)。
---|---
![[IM Output]](../static/img/compose/gradient_op_plus.png)
Plus ( )(将颜色相加以形成混合)
将叠加图像的颜色与背景相加。本质上会使两幅图像均等地混合在一起。其公式很自然地为:_Src_ + _Dest_。但请注意,如果相加后的颜色超出颜色范围限制,颜色会被正常的颜色范围限制所裁剪。这就是为什么在结果渐变图像中有一半是纯白色的原因,因为这些数值在其最大值处被裁剪了。建议谨慎操作,以确保在不希望被裁剪的情况下结果图像不会被裁剪。该运算符有若干主要用途。其一是合并包含独立通道颜色、但每个通道各自只有颜色的图像。例如……
magick -size 60x60 xc:none -fill red \
-draw 'circle 30,21 30,3' compose_R.png
magick -size 60x60 xc:none -fill lime \
-draw 'circle 39,39 36,57' compose_G.png
magick -size 60x60 xc:none -fill blue \
-draw 'circle 21,39 24,57' compose_B.png
magick composite -compose plus compose_R.png compose_G.png compose_plus_RG.png
magick composite -compose plus compose_R.png compose_B.png compose_plus_RB.png
magick composite -compose plus compose_G.png compose_B.png compose_plus_GB.png
magick composite -compose plus compose_R.png compose_plus_GB.png \
compose_plus_RGB.png
| 由于 IM 遵循 SVG 标准,“green”并不是真正的绿色(不像在 X11 颜色名称中那样),而是一种深绿或半亮的绿色。真正的 RGB 绿色可以用颜色“lime”指定,正如我们在上面的示例中所做的那样。
---|---
它还被用作一种数学运算符,用于将多个独立的渐变图像相加。例如在计算“曼哈顿”差异图像,或在渐变数学运算中。“[Plus](#plus)”有时被用来将白色文字添加到图像上。这种用法并不正确,可能会导致一些抗锯齿方面的不一致。更好的方法是使用“[Screen](#screen)”合成方法。它使用的是乘法而非加法的方式来增加亮度。线性减淡合成方法等价于“[Plus](#plus)”,但使用的是更常见的“[Over](#over)” alpha 混合方式。
Plus 与 Plus 混合
“[Plus](#plus)”之所以更为重要,是因为它几乎是唯一实现了不同于“[Over](#over)”混合方式的数学运算符。它不仅“相加”颜色,还“相加” alpha 通道数值,这也是它默认情况下几乎是唯一这样做的运算符。这一点很重要,因为它使得正确合并互补的蒙版图像成为可能。例如,参见 Dst In 与 Out 图像的合并。它还使你能够利用透明度来生成两幅图像的加权平均,即混合(Blend)。如果没有“[Plus](#plus)”这种特殊的混合方式,这些特殊的透明度处理技巧通常将无法实现。
从 IM v6.6.1-6 开始,所有数学合成方法都新增了在 alpha 通道上使用数学运算符的功能,方法很简单,只需移除默认的“Sync”标志,也就是从“[-channel](https://imagemagick.org/command-line-options/#channel)”设置中只指定你想应用该运算的具体通道。详见下文的使用图像合成进行图像通道数学运算。这意味着“[Plus](#plus)”运算符是数学合成方法中唯一不受此新特性影响的运算符,因为它默认已经启用了该行为。
![[IM Output]](../static/img/compose/gradient_op_minus.png)
Minus、Minus_Dst、Minus_Src ( )
其结果是一幅图像减去另一幅图像。哪幅图像被另一幅减去,取决于应用的是“Minus_Src”还是“Minus_Dst”。具体来说,“Minus_Dst”意为“减去目标”,若应用在“magick composite”命令中……“Minus_Dst”的公式为 _Src_ - _Dest_,“Minus_Src”的公式为 _Dest_ - _Src_。由于图像合成及“magick composite”命令中通常定义的图像顺序,原始方法“Minus”的含义是……
**{_Source_} Minus {_background_}**
****
也就是说,原始方法名“Minus”是“Minus_Dst”的同义词,意为“减去目标”。它也是用于定义所显示渐变图的运算符。例如,从上面“[Plus](#plus)”运算结果中减去一个圆形。 |
magick composite compose_plus_RGB.png -compose minus_dst compose_R.png \
compose_minus.png
![[IM Output]](../static/img/compose/compose_minus.png)
请注意 alpha 通道的处理方式,除“[Plus](#plus)”外,与其他数学运算符相同。参见数学合成与 Alpha 混合。可以通过特殊的“Sync”通道标志来修改此处理方式。详情参见下面的图像通道数学运算。“[Linear Burn](#linearburn)”合成方法也可用于颜色相减,但其做法是由用户对要相减的图像取反。更多详情参见线性加深合成方法。 | 在 IM v6.6.8-5 之前,只提供了原始的“[Minus](#minus)”方法(相当于较新的“[Minus_Dst](#minusdst)”)。
---|---
![[IM Output]](../static/img/compose/gradient_op_modulusadd.png)
ModulusAdd
“[ModulusAdd](#modulus_add)”与“[Plus](#plus)”非常相似,不同之处在于当结果超过白色时,会以取模方式回绕到黑色。例如,如果我们将两个灰度渐变相加,最亮的颜色会回绕形成第二个渐变。 |
magick -size 60x60 gradient: gradient.png
magick composite gradient.png gradient.png -compose ModulusAdd compose_add.png
magick composite gradient.png \( gradient.png -rotate -90 \) \
-compose ModulusAdd gradient_diagonal.png
magick gradient.png \( +clone +clone +clone +clone \) \
-background gray50 -compose ModulusAdd -flatten gradient_venetian.png
![[IM Output]](../static/img/compose/gradient_venetian.png)
这会生成一个重复 5 次的渐变。请注意我是如何使用“gray50”作为背景,从而有效地将渐变‘滚动’前移半个取模周期的。 ![[IM Output]](../static/img/compose/gradient_op_modulussubtract.png)
ModulusSubtract
“[ModulusSubtract](#modulus_subtract)”运算符与“[Minus](#minus)”相同,不同之处在于它是取模相减。从‘灰色’中减去‘白色’会得到原始的‘灰色’,而不是黑色,因为数值会回绕。取模相减的一个副作用是,某些部分可能会以看似不受控制的方式变成白色而不是黑色。 |
magick composite -compose subtract compose_plus_RGB.png compose_R.png \
compose_subtract.png
![[IM Output]](../static/img/compose/compose_subtract.png)
执行“[ModulusAdd](#modulus_add)”并配合取反图像,会产生相同的结果。 ![[IM Output]](../static/img/compose/gradient_op_difference.png)
Difference(图像比较与选择性取反)
结果图像是颜色值的绝对差值。其公式为:abs(_Src_ - _Dest_) 'black' 与 'white' 之差会产生最大结果——白色,而任何相同的颜色都会产生黑色。基本上这是一种简单的图像比较形式。这种合成方法更常见的用途是比较两张相同尺寸的图像有何不同,甚至可以生成差异的百分比。该运算符通常用于生成比较差异图像。该运算符也可用于选择性地对图像取反。叠加黑色对背景没有影响,而在该位置叠加白色则会使图像中的颜色取反。换句话说,此运算符(以及下一个)提供了一种基于图像映射的取反运算符。例如,让我们把玫瑰图像的一半取反。 |
magick -size 2x1 pattern:gray50 -scale 70x50\! black_n_white.gif
magick composite black_n_white.gif rose: \
-gravity center -compose difference compose_negate.gif
Exclusion(排除灰色的图像差异)
其公式为:_Src_ + _Dest_ - 2*_Src_ *_Dest_ 这大致是一种平均化的差异。白色叠加白色会产生黑色(无差异),黑色叠加黑色同理。然而灰色叠加灰色会产生灰色结果。白色与黑色叠加自然仍会产生白色(最大差异)。另一种理解方式是,明亮的图像区域会导致对方图层发生反转,而非常暗的区域则完全不会改变任何东西。从这个意义上说,Exclusion 方法与前面的“[Difference](#difference)”相同。该运算符的一个用途是用于乘以‘偏置渐变’,例如用于位移贴图的渐变。这类渐变将 50% 灰度值视为‘零’,较暗的颜色代表‘负’值,较亮的颜色代表‘正’值,取值范围为 -1 到 +1。详情参见乘以偏置渐变。该合成方法的另一个用途,由 Joe Fry 提交,是一种将多张差异图像合并在一起的方法。最终图像会显示所有图像的变化,而不仅仅是两张图像之间的变化。也就是说,给定图像 A、B 和 C,先生成 A、B 以及 B、C 的差异图像,然后对这些结果使用 Exclusion,这样就能得到一张显示所有三张图像如何变化的图像。此方法还与 Xor 合成混合运算符处理 alpha 透明度值的方式密切相关。
![[IM Output]](../static/img/compose/gradient_op_lighten.png)
Lighten and Darken(选取最大/最小值)
| 比较源图像和目标图像的颜色值,取相对较亮或较暗的值。Lighten 的公式为: | 若 _Src_ > _Dest_ |
则取 _Src_ |
|---|---|---|
否则取 _Dest_ |
||
| 对于 Darken,只需反转比较即可。 |
'[Lighten](#lighten)' 的一个用途是合成原始图像的模糊版本,使原始图像中的“高光”部分获得柔和的光晕效果。
magick flower_sm.jpg \( +clone -blur 0x3 \) \
-compose Lighten -composite flower_softglow.jpg
要获得更好的效果(使用“混合模糊技术”),请参见 柔和模糊,那是一种能取得类似结果的更好方法。
这些运算符的原理是比较并选取各个 RGB 通道的值,因此可能会导致一定的色彩失真,尤其是在处理图像的原色时。例如,这里我们创建了一幅红色和蓝色的渐变图像,然后使用 lighten 将它们合成在一起。
magick -size 100x100 gradient:red-black -rotate 90 red_gradient.png
magick -size 100x100 gradient:blue-black blue_gradient.png
magick red_gradient.png blue_gradient.png \
-compose Lighten -composite lighten_by_value.png
由于红色渐变图像中蓝色通道为零,反之亦然,而'[Lighten](#lighten)' 合成是按颜色值进行的,因此结果只是红色和蓝色图像的简单合并,从而产生一幅红蓝渐变图像。也就是说,上面的例子等同于一个简单的 通道复制合成。防止色彩失真的一种方法,是将该运算符限制为只调整图像的 HSL 色彩空间中的“Lightness(明度)”通道。不过这种方法并不总能得到理想的效果。 | _注意,“Gimp”、“Photoshop”、“PhotoLine”、“Paint Shop Pro”都和 IM 一样,直接比较各通道。
“Photo-Paint”则是通过比较图像的颜色强度来决定从哪幅图像中选取颜色,从而保持颜色的完整性。参见下面的 Lighten-Intensity 方法。
另一方面,“Picture Publisher”和“PhotoImpact”则使用颜色的明度(由 HSL 色彩空间定义)进行比较。
关于不同色彩空间下灰度差异的比较,请参见示例 使用色彩空间进行灰度化。
Lighten-Intensity 与 Darken-Intensity(按强度选取颜色)
自 IM v6.6.9-5 起,新增了 'Lighten_Intensity' 和 'Darken_Intensity' 变体。它会比较两幅图像中像素的强度,然后根据比较结果选取像素值。这意味着不会向图像中添加任何新颜色,不过新图像会是两幅图像颜色的混合体。同时图像顺序也无关紧要,只是尺寸和元数据来自目标图像。例如,这里取一幅红色渐变图像和一幅蓝色渐变图像中较亮的部分。
magick red_gradient.png blue_gradient.png \
-compose Lighten_Intensity -composite lighten_intensity.png
| 如你所见,整个像素都是从被选中的图像中取得的,颜色通道之间不会发生混合。然而,由于蓝色的强度被认为比红色暗,所以只有最暗的红色才会被较暗的蓝色渐变图像所替代。 | 该合成方法并未在此前我们讨论过的所有合成方法所依据的 SVG 合成指南 (2009) 中定义。因此,对于 alpha 通道应如何影响像素比较,并没有正式的定义。 |
|---|---|
关于 alpha ,该方法有两种运作模式。在启用特殊的 'Sync' 标志时,也就是在“[-channel](https://imagemagick.org/command-line-options/#channel)”设置中保留默认标志时,比较将基于颜色的强度,并按 alpha(透明度)通道加权。也就是说,“半透明白色”的加权强度大致与“不透明的中灰色”相当。
这意味着在其他条件相同的情况下,'[Lighten_Intensity](#lighten_intensity)' 会创建各形状图像的“并集”,而 '[Darken_Intensity](#darken_intensity)' 则会创建(至少非黑色)各形状图像的“交集”。这并不理想,将来可能会改变,但总比没有 alpha 输入要好。
第二种运作模式会在你关闭 'Sync' 通道标志时使用(参见下面的 使用 'Sync' 标志),例如使用“-channel All”。此时像素的选取将纯粹基于颜色强度,不受任何 alpha 加权的影响。不过,实际被选中的像素数据所带的 alpha 通道值仍会被复制过来。对于没有透明度的图像,无论采用哪种模式,结果都是一样的。这第二种模式还允许你使用更严格的“[-channel](https://imagemagick.org/command-line-options/#channel)”设定,来限定选中时可以从源图像复制到目标图像的通道。不过选取本身仍然只基于未加权的颜色强度。这意味着你可以更方便地根据两幅图像中颜色的强度,创建一个选取用的“形状蒙版”。你基于颜色强度比较两幅图像,但只关心结果中的 alpha 通道值。要制作这样的“蒙版”,可以使用 Alpha Transparent 让一幅图像完全透明(但仍保留颜色),另一幅图像保持完全不透明(默认状态)。最后可以使用 Alpha Extract 获取该像素位置上哪幅图像颜色更亮的蒙版。 |
magick red_gradient.png -alpha transparent blue_gradient.png \
-compose Lighten_Intensity -composite \
-alpha extract lighten_intensity_mask.png
![[IM Output]](../static/img/compose/lighten_intensity_mask.png)
请注意,两幅图像中的 alpha 值不一定只能是“开”与“关”,也可以设为某个“参考”值。这意味着你可以拥有一整个图像序列,每幅图像的 alpha 通道值各不相同。然后你就可以用这种合成方法把所有图像放在一起比较,得出图像中每个位置上哪幅图像的像素最亮(或最暗)的映射图。换句话说,强度合成方法可以用作一种针对长串图像的“选取”或“比较”运算符。 | 自 IM v6.6.9-5 新增。但目前尚未找到该方法的正式定义。因此当前的实现被归类为高度实验性,可能会根据用户建议而变化。不过其基本思路是合理的。
---|---
适用于旧版本 IM 的强度替代方案
如果你的 ImageMagick 版本没有 '[Lighten_Intensity](#lighten_intensity)' 方法,你可以通过对两幅图像的灰度副本使用 '[Lighten](#lighten)',并将结果与灰度副本进行比较,从而创建一个应用于原图像的选取蒙版,来重现一个纯粹只基于颜色的版本。这并不容易,下面是其中一种解决方案…… |
magick red_gradient.png blue_gradient.png \
\( -clone 0--1 -colorspace Gray \
\( -clone 0--1 -compose Lighten -composite \) \
-delete 1 -compose Difference -composite -threshold 0 \
\) -compose Src -composite intensity_lightened.png
![[IM Output]](../static/img/compose/intensity_lightened.png)
这是相当糟糕的一段处理过程,但如你所见,它是有效的。要得到'[Darken_Intensity](#darken_intensity)'版本,将"-delete 1"替换为"-delete 0",或者,将"-compose Lighten"替换为"-compose Darken"。两种方式都可行。
集合论等价操作
上面的许多数学方法也被用于对形状执行集合论或布尔运算。'[Lighten](#lighten)'合成方法可用于求两个(或多个)像素组(集合)的'并集 '(布尔'或 ')。
magick -size 64x64 xc: -draw 'circle 22,32 5,32' -negate circle_left.gif
magick -size 64x64 xc: -draw 'circle 41,32 58,32' -negate circle_right.gif
magick circle_left.gif circle_right.gif \
-compose Lighten -composite circle_union.gif
'[Darken](#darken)'合成方法产生像素的'交集 '(布尔'与 ')。
magick circle_left.gif circle_right.gif \
-compose Darken -composite circle_intersection.gif
'[Difference](#difference)'合成方法产生两个集合的'异或 '(布尔'XOR ')。
magick circle_left.gif circle_right.gif \
-compose Difference -composite circle_disjunction.gif
'[Exclusion](#exclusion)'方法也可以用于此目的,不过它对灰度(非布尔)值的处理方式不同。然而它正是用于'[XOR](#xor)' Duff-Porter alpha 混合的方法。最后,'[Minus](#minus)'可用于生成两个像素集合的'相对补集 '。
magick circle_left.gif circle_right.gif \
-compose Minus_Src -composite circle_complement.gif
注意,在应用上述任何一种"集合"或"布尔"合成方法时,可能需要使用"[-clamp](https://imagemagick.org/command-line-options/#clamp)",以防止 HDRI 版本的 ImageMagick 生成超出范围的值。
数学合成与 alpha 混合
你可以使用上述数学合成方法对图像执行数学运算。然而这里有一个主要的注意事项。对于包含透明度的图像,它可能不会像你期望的那样工作。默认情况下,几乎所有上述数学合成都遵循 SVG 规范所定义的约定。SVG 合成指南 (2009)。这意味着,如果你尝试在带有 alpha 通道(即某种形式的透明度)的图像上使用数学合成,你可能得不到真正的数学合成,而是一种"混合"形式的合成。例如,这里我创建了带有一些周边透明区域的渐变图像。然后我将它们'[Multiply](#)'(相乘)在一起。
magick -size 64x64 xc:none -draw 'rectangle 20,0 43,63' \
gradient: -compose In -composite alpha_src.png
magick alpha_src.png -transverse alpha_dst.png
magick alpha_dst.png alpha_src.png \
-compose Multiply -composite alpha_result.png
![[IM Output]](../static/img/compose/alpha_src.png)
源图像 | | ![[IM Output]](../static/img/compose/alpha_dst.png)
目标图像 | | ![[IM Output]](../static/img/compose/alpha_result.png)
结果
---|---|---|---|---
注意,图像中未重叠的部分只是被原样简单地包含到结果图像中,没有做任何修改。也就是说,这些图像被"混合在一起"了。更糟糕的是,如果图像包含部分透明度,颜色值将按 alpha 通道进行"加权"。这对于加法合成(提供"加权颜色相加")或混合操作是有用的,但我目前还没有想出图像中"颜色加权相乘"有什么用处。有人知道吗? 如果你是在做图像数学运算,这种行为通常是不希望出现的。不过在做此类数学运算时,你通常也不会有任何 alpha 通道,所以"alpha 混合"和"加权颜色"的问题很少出现。 | _加法合成是唯一一个不做"覆盖式 alpha 混合"的数学合成方法。相反,按照 SVG 规范,它对每个通道分别相加。不过颜色通道在相加之前仍然会按 alpha 值加权,只是 alpha 值的处理方式(混合方式)不同。
这对于正确提供蒙版形状的"相加"很重要,如DstOut 合成中所演示的那样。_
---|---
使用图像合成实现图像通道数学运算
如果你使用的图像仅仅是完全不透明的灰度图像,那么可以直接在其上应用数学合成方法而不会有任何问题。但是默认情况下,合成方法会像上面所看到的那样,对所有颜色通道应用 alpha 混合。这使得将其仅应用于特定通道(例如 alpha 通道)变得困难。例如,这里我对两张包含透明渐变的黑色图像执行'[Multiply](#multiply)'(相乘)操作。使用默认的"[-channel](https://imagemagick.org/command-line-options/#channel)"设置。
magick -size 64x64 gradient:black-none alpha_grad_src.png
magick alpha_grad_src.png -transverse alpha_grad_dst.png
magick alpha_grad_dst.png alpha_grad_src.png \
-compose Multiply -composite alpha_grad_result.png
![[IM Output]](../static/img/compose/alpha_grad_src.png)
源图像 | | ![[IM Output]](../static/img/compose/alpha_grad_dst.png)
目标图像 | | ![[IM Output]](../static/img/compose/alpha_grad_result.png)
结果
---|---|---|---|---
请注意,'Black'与'Black'相乘的结果是'Black',因此在这个例子中颜色没有变化。只有最终的透明度被修改了。但是这个结果绝对不是图像 alpha 通道值的相乘,因为根据SVG 定义,半透明部分是使用'over'方法进行混合的。这在数学上等价于 alpha 通道的'[Screen](#screen)'(滤色)合成,而不是相乘。
同步通道标志与数学合成
从 IM v6.6.1-6 开始,数学合成方法被修改为遵循'Sync'(同步)标志,也就是"[-channel](https://imagemagick.org/command-line-options/#channel)"设置中的这个标志。这个标志实际上意味着"同步颜色通道和 alpha 通道的操作"。默认的"[-channel](https://imagemagick.org/command-line-options/#channel)"设置是'RGBK,Sync'。因此默认情况下,颜色通道和 alpha 通道会按照 SVG 规范"同步"进行适当处理。然而,如果去掉'Sync'标志,数学合成方法将变为"通道运算符",对每个通道分别应用数学函数。 |
magick alpha_grad_dst.png alpha_grad_src.png \
-channel RGBA -compose Multiply -composite alpha_grad_nosync.png
![[IM Output]](../static/img/compose/alpha_grad_nosync.png)
这才是 alpha 通道的正确相乘结果。
以上所有内容仅适用于数学合成方法(如上文所述)以及特殊的'[Mathematics](#mathematics)'合成方法(见下文)。它不适用于其他合成方法,例如光照合成方法(见下一节)。至少目前还不适用。'Sync'标志也会影响基于亮度的加亮/加暗合成方法(并非 SVG 定义的合成方法)处理 alpha 通道的方式(如上所述)。有关使用图像数学运算的更多信息,请参见渐变数学运算。更具体地说,那些示例研究了如何使用数学合成来生成偏置渐变图像,这稍微复杂一些。
光照合成方法 —— 加光、减淡、加深
这些方法以高度复杂的方式修改图像的颜色,通常用于调整图像的阴影或亮度,使某些区域变亮,另一些区域变暗。
- 光照合成方法可分为三个相关运算符的子类别。
- '加深(Burn)',通常使图像变暗。
- '减淡(Dodge)',通常使图像变亮。
- '加光(Light)',根据其中一张图像的明暗程度,同时使图像变暗和变亮。
'[Multiply](#multiply)'(使颜色变暗)通常被认为是纯粹的'加深'合成操作,而'[Screen](#screen)'(变亮)则是'减淡'合成运算符。通常其中一张图像由彩色图案或照片组成,而另一张则是用于适当地使图像变亮或变暗的灰度图像。哪张图像应该是彩色图像,哪张应该是灰度图像,这是有争议的,取决于该方法的具体实现方式。在这方面没有标准,因此建议谨慎并进行实验。由于这些运算符缺乏标准,许多用户并不理解或误用了这些运算符。我也一直没有找到任何关于正确使用这些合成方法的指南,几乎可以说是不存在的,所以我只能在下面的示例中尽力而为。 ![[IM Output]](../static/img/compose/gradient_op_overlay.png)
Overlay(为灰度对象添加颜色)
这种合成方法非常特殊,因为它被设计为同时对图像进行'[Multiply](#multiply)'(变暗)和'[Screen](#screen)'(变亮)处理。对某个特定像素应用哪种方法,取决于目标图像的值,该值可以视为"光照蒙版"。因此,目标图像通常是一张灰度图像,颜色将被添加到其中。其公式为: |
如果 _Dest_ <= 0.5 |
则 | 2*_Src_ *_Dest_ |
|---|---|---|---|
| 否则 | 1-2*(1-_Src_)*(1-_Dest_) |
||
| 其结果是一种特殊的合成方法,它会保留目标图像中存在的任何纯白和纯黑(高光)部分,同时用叠加图像中的颜色为该图像的中间调灰色区域着色。也就是说,给定一张灰度图像作为目标图像,这个运算符将使用源图像为该背景着色,同时保留目标图像中存在的任何阴影和高光效果。 |
magick -size 64x64 gradient:yellow-blue gradient_yell-blue.jpg
magick -size 64x64 gradient: -rotate 90 gradient_grey.jpg
magick gradient_grey.jpg gradient_yell-blue.jpg \
-compose Overlay -composite compose_overlay_gradients.jpg
![[IM Output]](../static/img/compose/gradient_grey.jpg)
目标图像 | | ![[IM Output]](../static/img/compose/gradient_yell-blue.jpg)
叠加图像 | | ![[IM Output]](../static/img/compose/compose_overlay_gradients.jpg)
结果
---|---|---|---|---
正如你所看到的,渐变图像的中间调灰色区域被所提供图像的颜色着色了。这正是这种合成方法的正常用法,即为灰度光照蒙版添加颜色。与'[Multiply](#multiply)'或'[Screen](#screen)'不同,这种方法不具有结合律。
magick gradient_yell-blue.jpg gradient_grey.jpg \
-compose Overlay -composite compose_overlay_gradients2.jpg
![[IM Output]](../static/img/compose/gradient_yell-blue.jpg)
目标图像 | | ![[IM Output]](../static/img/compose/gradient_grey.jpg)
叠加 | | ![[IM Output]](../static/img/compose/compose_overlay_gradients2.jpg)
结果
---|---|---|---|---
这种把"叠加颜色"用于灰度高光图像的方式,非常适合为"[-shade](https://imagemagick.org/command-line-options/#shade)"运算符的输出结果添加颜色。不过你需要非常小心,确保该运算符生成的是完美的中间调灰色,这样在没有高光的区域才能得到正确的着色。详情请参见Shade 叠加高光。例如,给定一个圆形,我们可以先对其进行 shade 处理以产生立体效果,然后用原始图像对结果进行着色,从而恢复原始颜色。
magick -size 64x64 xc:dodgerblue \
-draw 'fill skyblue circle 32,32 7,27' circle_blue.jpg
magick circle_blue.jpg -shade 120x30 -auto-level circle_shaded.jpg
magick circle_shaded.jpg circle_blue.jpg \
-compose Overlay -composite circle_shaded_tinted.jpg
![[IM Output]](../static/img/compose/circle_shaded.jpg)
目标 | | ![[IM Output]](../static/img/compose/circle_blue.jpg)
叠加 | | ![[IM Output]](../static/img/compose/circle_shaded_tinted.jpg)
结果
---|---|---|---|---
关于使用"[Overlay](#overlay)"方法更实用的例子,请参见背景生成器示例页面中的"levels_3d"图像。这种合成方法最大的问题在于,两幅图像中的任何透明度都不会被保留。也就是说,在任一图像中可见的内容都会在结果中可见。通常这个运算符用于不含透明度的图像,这意味着你可能需要额外的步骤来恢复目标图像或背景图像的透明度。保留透明度的一种简单方法是,直接关闭目标图像的 Alpha 通道,使其不可访问。合成完成后,你可以再次将其打开。阴影形状图像中给出了这种做法的一个例子。另一种方法是保存一份"蒙版",或者原始图像的副本,然后用该蒙版或图像恢复透明度。叠加颜色着色中提供了这样做的例子。或者参见更复杂的例子更好的 3D 徽标生成。 |
直到 IM 6.1.6 版本为止,'Overlay' 合成方法一直存在缺陷,只能产生纯黑或纯白的结果(很可能你只会得到纯黑的结果)。因此,大多数 IM 用户几乎没有机会理解这个运算符。现在这个问题已经修复,用户将能够很好地利用这个方法。 |
|---|---|
![]() |
Hard_Light(为图像添加纹理或高光/阴影)
这与"[Overlay](#overlay)"相同,只是源图像和目标图像互换了。如果你比较这两个运算符的渐变图像,会发现渐变呈对角线转置,显示出源图像与目标图像输入的互换。其公式为: |
如果 _Src_ <= 0.5 |
则 | 2*_Src_ *_Dest_ |
|---|---|---|---|
| 否则 | 1-2*(1-_Src_)*(1-_Dest_) |
||
因此,"[Overlay](#overlay)"可以为灰度阴影对象添加颜色,而"[Hard_Light](#hardlight)"则是为图像添加灰度光照效果。使用哪种方法取决于你在添加图像光照效果时的思路。重要的区别在于哪幅图像是"目标"图像,从而保留图像元数据,甚至可以在操作期间临时禁用 Alpha 通道以保留它。例如,这里我用与原图相同尺寸的纯灰色图像,通过模糊的"[-raise](https://imagemagick.org/command-line-options/#raise)"操作生成一种"光照效果"。然后使用"[Hard_Light](#hardlight)"进行合成,把这些光照效果添加到图像中。 |
magick rose: -fill gray50 -colorize 100% \
-raise 4 -normalize -blur 0x4 lighting_effect.png
magick rose: lighting_effect.png \
-compose hardlight -composite compose_hardlight.png
![[IM Output]](../static/img/images/rose.png)
目标 | | ![[IM Output]](../static/img/compose/lighting_effect.png)
叠加 | | ![[IM Output]](../static/img/compose/compose_hardlight.png)
结果
---|---|---|---|---
这种方法只需一次操作,就能轻松地为现有图像添加高光(如反射光)或暗部阴影效果。下面是直接为图像添加光照"纹理"的例子。 |
magick rose: \( granite: -blur 0x.5 -normalize \) \
-compose hardlight -composite compose_texture.png
![[IM Output]](../static/img/compose/compose_texture.png)
注意结果的效果有多强烈,明暗区域几乎淹没了原始图像。这就是使用"[Hard_Light](#hardlight)"的缺点。为了解决这个问题,你可能想要减弱叠加纹理的对比度。 |
magick rose: \
\( granite: -blur 0x.5 -normalize +level 30,70% \) \
-compose hardlight -composite compose_texture_muted.png
![[IM Output]](../static/img/compose/compose_texture_muted.png)
其他光照合成方法,例如"[Soft_Light](#softlight)",可能会更直接地产生更好的效果。更好的例子请参见叠加纹理,它位于照片食谱中。关于使用"[Hard_Light](#hardlight)"着色的一个实际例子,参见 IM 论坛中关于从平面源图像生成 3D DVD 封面的讨论。请记住,"[Overlay](#overlay)"和"[Hard_Light](#hardlight)"着色本质上是同一种合成方法,唯一的区别在于图像的顺序。 ![[IM Output]](../static/img/compose/gradient_op_softlight.png)
Soft_Light(更柔和的图像高光)
"Soft_Light"合成方法同样会为现有的彩色图像添加高光和阴影。不过,目标图像的颜色会被修改,从而在光照效果上产生更柔和的对比度和更平滑的渐变。如果你仔细观察"灰度映射图像"(见右图),会发现没有明显的突变,尽管实际上存在两处。(另见下文的"[Pegtop_Light](#pegtoplight)")。它与"[Overlay](#overlay)"合成方法的关系比与"[Hard_Light](#hardlight)"更密切,因此目标图像通常是灰度光照蒙版。这是否是有意为之尚不清楚,但这确实使它与"[Hard_Light](#hardlight)"不同,这意味着你最好把主图像合成到阴影图像上,而不是反过来。 :-( | _警告: 这种光照效果的定义更接近"[Overlay](#overlay)"而不是"[Hardlight](#hardlight)"。然而,哪一方应该包含灰度光照图像尚不清楚。使用源图像可以产生完全的黑白结果,而使用目标图像则无法产生这些极端效果。
如果有人有确切的参考资料,请告诉我。_
---|---
例如,这是"Soft_Light"纹理映射的例子。 |
magick rose: \( granite: -blur 0x.5 -normalize \) \
-compose softlight -composite compose_softlight.jpg
![[IM Output]](../static/img/compose/compose_softlight.jpg)
如你所见,即使使用经过归一化的"granite:"图像,颜色变化也比'[Hard_Light](#hardlight)'甚至'[Overlay](#overlay)'更柔和、更不强烈。不过你也永远不会在结果图像中得到纯黑色阴影或纯白色高光。基本上'[Soft_Light](#softlight)'具有更柔和的纹理效果,能保留源图像的原始色彩。这里展示了使用纯黑、纯白以及完美灰色叠加图像所产生的颜色变化。 |
magick -size 1x3 gradient: -sample 70x46\! grayscale_3.gif
magick composite grayscale_3.gif rose: -compose softlight compose_softlight_2.gif
![[IM Output]](../static/img/compose/grayscale_3.gif)
![[IM Output]](../static/img/compose/compose_softlight_2.gif)
如果用'[Hard_Light](#hardlight)'来做这件事,图像的两侧会变成纯黑和纯白,而不仅仅是50%的加深或提亮。 | _在 IM v6.5.4-3 之前,'[Soft_Light](#softlight)'的表现与预期不符,对任何非灰色调的叠加图像都会产生提亮效果。实际上我确认过,这是按照官方2004年 SVG 规范正确实现的。
遗憾的是,出问题的是规范本身,而非实现方式。这一点在2009年3月的 SVG 规范中得到了修正。因此从 IM v6.5.4-3 及以后版本开始,该运算符的表现就如同你所期望的柔光效果一样了。_
---|---
![[IM Output]](../static/img/compose/gradient_op_pegtoplight.png)
Pegtop_Light(柔光的更平滑变体)
虽然'[Soft_Light](#softlight)'已经比'[Hard_Light](#softlight)'或'[Overlay](#overlay)'平滑得多,但它实际上仍然是由两个独立函数拼接而成的。'Pegtop_Light'方法产生的结果与'[Soft_Light](#softlight)'几乎相同,但使用的是单一平滑函数,不存在任何不连续点,甚至连'[Soft_Light](#softlight)'所用的两个细微不连续点也没有。正因如此,它实际上要简单得多、也快得多。其公式为:2*_Src_ *_Dest_ + _Src_ 2*(1 - 2*_Dest_) 详情参见Pegtop SoftLight Alternative页面。 |
警告: 该光照效果的定义更接近'[Overlay](#overlay)'而不是'[Hard Light](#hardlight)'。 |
|---|---|
'[Pegtop_Light](#pegtoplight)'合成方法是在 IM 6.5.4-3 版本中新增的。 |
|
| --- | --- |
![]() |
Linear_Light(一种非常简单但效果强烈的光照方案)
Vivid_Light(Linear Light 的一种变体)
Pin_Light
Linear_Dodge(Photoshop 的"Add"合成)
如果你将'Linear Dodge'的渐变图像(右侧)与'[Plus](#plus)'的进行比较,会发现对于两幅不透明图像而言,两者的效果完全相同。其公式当然是:Src + Dest 也就是说,对于没有透明度的图像,以下两条命令使用图像'A'和'B'会产生相同的结果图像'R'...
magick A B -compose Plus -composite R
magick A B -compose LinearDodge -composite R
| 该方法等同于 Photoshop 中同名的合成模式。两种方法之间唯一真正的区别在于它们处理含半透明颜色的图像的方式。本质上,Linear_Dodge 合成使用的是"Over" alpha 混合,而Plus 合成使用的是"Plus" alpha 混合。详情参见Plus 混合。 | '[Linear_Dodge](#lineardodge)'合成方法是在 IM 6.5.4-3 版本中新增的。 |
|---|---|
![]() |
Linear_Burn(Photoshop 的"Subtract"方法)
'Linear Burn'合成方法是一种"相加再减一"的合成,其结果等同于对'[Linear Dodge](#lineardodger)'或'[Plus](#plus)'合成方法的所有输入和输出图像取反后得到的结果。其公式为:_Src_ + _Dest_ - 1 在 Photoshop 中,这不仅被称为'Linear Burn',也被称为'Subtract'。也就是说,如果你对其中一幅输入图像(例如源图像)进行取反,那么该图像就会从另一幅图像中被减去。例如,当你对源图像取反时,运算结果如下...
(1-_Src_) + _Dest_ - 1 ==> _Dest_ - _Src_
也就是说,在没有透明度的情况下,你可以用图像'A'减去图像'B',得到相同的结果图像'R'...
magick A B -compose minus_src -composite R
magick B A -compose minus_dst -composite R
magick A \( B -negate \) -compose linear_burn -composite R
magick B -negate A -compose linear_burn -composite R
基本上,被负片处理的那张图像,就是"[Linear Burn](#linearburn)"用来从另一张图像中减去的图像。图像是源图像还是目标图像并不重要。从某种意义上说,这使得这种合成方法更加灵活。举例来说,这里我用右边的圆形图像(先将其负片化),从左边的图像中减去。
magick circle_left.gif \( circle_right.gif -negate \) \
-compose LinearBurn -composite circle_subtract.gif
这种合成方法也可以作为减法运算序列方法的替代方案,用于从单个起始图像中减去多张图像。不过要注意,"[Linear Burn](#linearburn)"不能直接应用于图像的 alpha 通道,而更数学化的合成方法中的Minus则可以。 |
"[Linear_Burn](#lineardodge)"合成方法是在 IM 6.5.4-3 版本中加入的。 |
|---|---|
![]() |
Color_Dodge(photoshop 除法)
这种合成方法把源叠加图像当作一种蒙版,用来在长时间内保护背景图像免受"曝光"。曝光在较亮蒙版下的部分会变得更亮(即被"减淡"),而黑色区域则不发生变化。可以把它想象成把一个物体长时间放在照片上,随着时间推移,被光照到的部分会逐渐随年月而变白,而被遮盖的部分则保持原样。纯黑色叠加图像不会改变图像,而纯白色叠加图像会使所有背景颜色变白,纯黑色的部分除外。然而,与"[Screen](#screen)"(反相乘法)或"[Linear_Dodge](#lineardodge)"(相加)这两种减淡合成方法不同,纯黑或全白的目标图像不会受到光照蒙版的影响。换句话说,只有包含灰色和非纯色的区域才会受到影响。它的公式是:_Dest_ / (1-_Src_) 这里需要示例和实际用途 实际上,"[ColorDodge](#colordodge)"和两种"[Divide](#divide)"运算符可以产生相同的结果。不过"[ColorDodge](#colordodge)"要求作为"除数"使用的图像先被负片化,然后作为运算符的"源"图像使用。举例来说,以下这些命令都是对图像"N"(分子)除以图像"D"(分母),结果都会得到相同的图像"R"……前提是所有图像尺寸相同。
magick N \( D -negate \) -compose ColorDodge -composite R
magick N D -compose DivideSrc -composite R
magick D N -compose DivideDst -composite R
关于如何利用图像相除来去除背景渐变的示例,请参见"[Divide](#divide)"。 ![[IM Output]](../static/img/compose/gradient_op_colorburn.png)
Color_Burn
这是"[Color_Dodge](#colordodge)"的反向操作,相当于把所有输入和输出图像都做负片处理。结果是背景图像会被较暗的蒙版图像加深,而白色则不产生加深效果。然而,与"[Multiply](#multiply)"或"[Linear_Burn](#linearburn)"这两种加深合成方法不同,纯黑或全白的目标图像不会受到光照蒙版的影响。换句话说,只有包含灰色和非纯色的区域才会受到影响。它的公式是:1 - ( (1-_Dest_) / _Src_) 这里需要示例和实际用途 这条命令等价于前面用来实现图像相除的那组公式。注意命令末尾的最后一次负片处理。
magick N -negate D -compose ColorBurn -composite -negate R
"[Color_Burn](#colorburn)"的一个用途是把暗色渐变背景清理为纯黑色。就像"[Color_Dodge](#colorburn)"可以把背景渐变处理为白色一样。 |
在 IM v6.5.4-3 之前,"[Color_Burn](#colorburn)"的实现被证实是错误的。 |
|---|---|
通道复制方法
这些图像合成方法专门用于把图像的通道信息从一张图像转移到另一张图像。不过它对被复制"通道"所在的图像做了一些假设。建议在使用这些方法之前,先阅读图像色彩空间和颜色通道运算符这两节,以了解 IM 在内存中是如何表示图像颜色通道的。最有用的通道复制合成方法是"Copy_Opacity"(见下文)。它是使用单独的灰度蒙版图像来完全替换(或添加)现有图像 alpha 通道的最简便方法。
Copy_Opacity(从灰度蒙版设置透明度)
"[Copy_Opacity](#copyopacity)"运算符最初的用途是把源图像的透明度通道复制到目标图像中,以设置该图像的透明部分。这项操作现在更常用 Duff-Porter 运算符来完成,因为这些运算符是专门为合成带 alpha 透明度的图像而设计的。举例来说,如果目标图像是完全不透明的(这也是该运算符典型的使用场景),那么"[Dst_In](#dstin)",甚至"Dst_ATop"运算符都能得到相同的结果。那么既然有替代方案,为什么"[Copy_Opacity](#copyopacity)"运算符仍然如此重要呢?答案在于这个运算符对一种特殊情况的处理方式。当叠加(源)图像没有 alpha 通道时,这个运算符会把它当作一张简单的灰度图像蒙版来处理。也就是说,它会用给定的灰度图像来替换该图像已有的 alpha 通道。总的来说,灰度图像中黑色的部分会被视为完全透明,白色部分则被视为完全不透明。这一点非常重要,也非常常用,我会把它当作一条经验法则来记住……
使用这个运算符的图像_不应_包含任何 alpha 通道。
可以通过对两张输入图像分别关闭 alpha 通道,来确保图像不含任何 alpha 通道,然后再使用"[Copy_Opacity](#copyopacity)"合成设置进行合成。举例来说,先制作一张灰度的月亮图像(画起来很简单),然后把它用作一张蓝色等离子渐变图像的蒙版,从而得到一个看起来带有斑驳纹理的蓝色月亮效果。 |
magick -size 70x70 xc:black -fill white -draw 'circle 35,35 35,5' \
-fill black -draw 'circle 28,30 35,5' \
moon_mask.gif
magick -size 70x70 plasma:white-dodgerblue moon_mask.gif \
-alpha Off -compose CopyOpacity -composite moon_gradient.png
![[IM Output]](../static/img/compose/moon_mask.gif)
![[IM Output]](../static/img/compose/moon_gradient.png)
如果你的图像带有需要保留的透明部分,那么这就不是你需要的 alpha 合成运算符。你更可能需要使用"[Dst_In](#dstin)",从目标图像中减去源叠加图像的透明区域(这种情况下两张图像都需要启用并使用 alpha 通道)。这个运算符在在字体中使用蒙版图像和编辑图像蒙版两节中有更详细的说明。它在本站其他许多示例中也被广泛使用。
Copy_Red, Copy_Green, Copy_Blue
把源图像指定的颜色通道复制到目标图像中。由于灰度 RGB 图像在三个颜色通道中拥有相同的数据,这些方法可以理解为把一张灰度通道图像复制过去,替换目标图像中指定的通道。这与"Copy_Opacity"(见上文)用灰度图像替换图像"alpha 通道"的做法类似。如今,由于可以通过各种颜色通道运算符来分离并重新组合颜色通道(借助灰度通道图像),这些通道复制方法已经很少被使用了。需要注意的是,在合并各种灰度渐变图案时,使用这些运算符可以生成非常有趣的彩色图像。相关示例可以参见原始合成运算符表中的颜色渐变组合。
Copy_Cyan, Copy_Magenta, Copy_Yellow
这些是与上一节相同方法的同义词。基本上,RGB 图像中的“Red”通道也被用作 CYMK 图像中的“Cyan”通道。“Green”和“Magenta”通道也是如此,“Blue”和“Yellow”通道同理。正因如此,复制“Cyan”通道与复制“Red”通道是一回事。图像数据所代表的通道类型,取决于内存中图像当前的色彩空间。
Copy_Black
这个方法同样只是将“Black”通道从源图像复制到目标图像(如果存在的话)。但该通道只存在于 CMYK 图像中。如果“Black”通道不存在,这个操作就什么也不做,这很可能是个 bug。它应该做的大概是:将一幅灰度的“Black”通道图像,复制到目标图像的黑色通道上(假设该通道存在)。
Hue(将 RGB 图像的色相复制到目标图像)
该操作符将源图像的色相 H 复制过来,替换目标图像的色相,而背景的饱和度 S 和亮度 L(还是应该是 luminance Y?)保持不变。这里假设两幅图像都处于 RGB 色彩空间。我尚未在非 RGB 色彩空间图像上测试过这一点。
Saturate(将 RGB 图像的饱和度复制到目标图像)
将源图像的饱和度 S 复制到目标图像(假设图像处于 RGB 色彩空间),而色相 H 和亮度 L(还是应该是 luminance Y?)保持不变。这里假设两幅图像都处于 RGB 色彩空间。我尚未在非 RGB 色彩空间图像上测试过这一点。
Luminize(将 RGB 图像的亮度复制到目标图像)
将源图像的亮度 L(还是应该是 luminance Y?)复制到目标图像,而色相 H 和饱和度 S 保持不变。这里假设两幅图像都以 RGB 色彩空间存储。我尚未在非 RGB 色彩空间图像上测试过这一点。
Colorize(将色相和饱和度复制到目标图像)
将源图像的色相 H 和饱和度 S 复制到目标图像,而色彩亮度 L(还是应该是 luminance Y?)保持不变。这里假设两幅图像都以 RGB 色彩空间存储。我尚未在非 RGB 色彩空间图像上测试过这一点。
将一幅图像溶解叠加到另一幅图像上
“[-dissolve](https://imagemagick.org/command-line-options/#dissolve)”操作符所做的,是提供一种可控的“[Over](#over)”合成方法。它会根据给定的百分比,在叠加图像叠放到背景之上之前,调整叠加图像的透明度。
**magick composite -dissolve {_percent_} overlay bgnd result
magick composite -dissolve {_src_percent_}x{_dst_percent_} overlay bgnd result
magick bgnd overlay -compose dissolve \
-define compose:args={_src_percent_},{_dst_percent_} \
-composite result
**
提供两个参数(IM v6 中的新特性),可以让你精确定义在图像叠放之前,叠加图像和背景图像各自要溶解掉多少。如果只给出一个百分比参数,那么只有叠加图像会被溶解到剩下这个比例(0% 表示完全透明,100% 表示源图像不变),然后再(使用“[Over](#over)”合成方法)叠放到背景之上。此外,如果数值继续超过 100%(同样是 IM v6 的新特性),接下来就会开始溶解背景图像。换句话说,在 0 到 100% 的范围内,背景图像完全不会被溶解(dst_percent 为 100%),而在 100% 到 200% 的范围内,叠加图像保持不变(src_percent 设为 100%),背景图像则被溶解,当参数达到 200% 时背景就完全消失了。下面是一张使用不同 dissolve 参数得到的结果表…… |
magick composite -dissolve {_argument_} -gravity South \
star.gif dragon_sm.gif -alpha Set {_result_}
可以看到,“[-dissolve](https://imagemagick.org/command-line-options/#dissolve)”会先将新图像缓慢溶解叠加到背景之上,然后再缓慢溶解掉原始的背景图像。这非常适合用于含有透明区域的图像。你也可以控制背景的溶解程度,这样在一幅图像在上方溶解的同时,你可以安排背景在下方逐渐溶解消失。这很不错,但并不太适合正统的幻灯片式图像切换溶解效果。因为当一幅图像被叠放上去时,两幅图像并不是被均匀地混合在一起,而且交换图像参数(以及对应的 dissolve 参数)会得到不同的结果。 |
要让 100% 到 200% 的范围,或者说第二个百分比参数起作用,背景图像必须包含 alpha 通道。这对于默认不含任何透明信息的 JPEG 图像来说尤其重要。 因此,最好先用“[-alpha](https://imagemagick.org/command-line-options/#alpha) Set”操作符让所有图像都带上 alpha 通道,然后再应用'dissolve'合成方法。 |
|---|---|
| 在两幅图像上同时使用 dissolve 时,最大的注意事项是透明度会影响到平均结果。也就是说,即便两幅输入图像都是完全不透明的,将两幅图像各溶解 50% 之后,结果颜色也总是会呈现半透明状态。例如: |
magick dragon_sm.gif star.gif -alpha on \
-compose dissolve -define compose:args='50,50' \
-gravity South -composite dissolve_50_50.png
magick composite -compose Dst_Over -tile pattern:checkerboard \
dissolve_50_50.png dissolve_50_50_bg.png
![[IM Output]](../static/img/compose/dissolve_50_50_bg.png)
可以看到,将该图像叠放到棋盘格背景之上后,图像的所有部分至少都是半透明的。不过实际叠加的部分,其透明程度要低于任一源图像本身透明的部分。只有当其中一幅图像(通常是“背景”)没有被溶解(即取值为 100%)而保持不透明时,才能从“Dissolve”合成中得到完全不透明的图像。这就是为什么默认情况下“背景”参数至少一开始会使用 100 这个值。以下是一些特定“[-dissolve](https://imagemagick.org/command-line-options/#dissolve)”参数所对应的特殊情况…… 0x0 | | 两幅图像都被溶解到完全透明。
等同于“[Clear](#clear)”合成方法。
---|---|---
0 | 只剩下背景图像不变(源图像变为透明)。
等同于“[Dst](#dst)”合成方法。
100 | 叠加图像正常叠放到背景图像之上。
相当于'[Over](#clear)'合成方法。
200 | 叠加图像在空白画布上(背景变为透明)。
相当于'[Src](#src)'合成方法。
"[-dissolve](https://imagemagick.org/command-line-options/#dissolve)"合成方法通常被用作用图像添加水印的另一种方式,尤其是彩色水印。
将两幅图像混合在一起
"[-blend](https://imagemagick.org/command-line-options/#blend)"合成方法提供的正是"[-dissolve](https://imagemagick.org/command-line-options/#dissolve)"合成方法最初打算提供的功能,只是后者后来被挪用于其他更基础的操作。"[-dissolve](https://imagemagick.org/command-line-options/#dissolve)"方法是把图像叠加在另一图像之上,而"[-blend](https://imagemagick.org/command-line-options/#blend)"则是根据给定的百分比参数,将两幅图像平等对待地合并在一起(只是简单相加)。因此,除了最终图像尺寸外,只要交换百分比和图像参数,就能得到相同的结果。这一点对"[-dissolve](https://imagemagick.org/command-line-options/#dissolve)"方法并不成立。换句话说,"[-blend](https://imagemagick.org/command-line-options/#blend)"是可交换的(参数可互换),而"[-dissolve](https://imagemagick.org/command-line-options/#dissolve)"则不是。
**magick composite -blend {_percent_} overlay bgnd result
magick composite -blend {_src_percent_}x{_dst_percent_} overlay bgnd result
magick bgnd overlay -compose blend \
-define compose:args={_src_percent_},{_dst_percent_} \
-composite result
**
如果只给出一个百分比值,它会被用作叠加图像的溶解百分比,而背景图像则以恰好相反的量溶解。也就是说,"-blend 30"会将叠加图像溶解30%,将背景图像溶解70%,然后再把两幅图像相加。因此它等同于"-blend 30x70"。这样做的结果是,两幅图像(在叠加区域)的不透明度加起来仍然是100%。
通过给出两个百分比,你可以精确控制两幅图像各自要合并进来多少。下面是使用不同溶解参数得到的结果表…… |
magick composite -blend {_argument_} -gravity South \
compose_R.png compose_plus_GB.png -alpha Set {_result_}
从结果中可以看出,"[-blend](https://imagemagick.org/command-line-options/#blend)"能让你在没有叠加感的情况下,将一幅图像平稳地替换为另一幅图像。如果你把混合结果叠加到一张黑色画布上(比如与你的显示器同尺寸),就可以轻松制作出一个像样的幻灯片放映程序,让一幅图像缓缓溶解为另一幅。你还会发现,由于图像是相加在一起的(内部使用的是'[Plus](#plus)'合成运算符),你很容易让颜色通道超出最大值,从而产生一些伪影。特别是100%的白色会导致另一幅图像完全不可见,因为所有颜色通道已经达到最大值。建议在大多数情况下,只需要使用单参数版本的blend即可。 |
与"-dissolve"一样,背景图像必须包含alpha 通道,"-blend"才能正确地溶解背景图像。 因此,最好先让 IM对所有图像设置alpha 通道,然后再应用'[Blend](#blend)'合成。 |
|---|---|
以下是针对特定"[-blend](https://imagemagick.org/command-line-options/#blend)"参数的特殊情况…… 0x0 |
|
相当于'[Clear](#clear)'合成方法。 |
|
| --- | --- |
0 |
只有背景图像保持不变。 |
相当于'[Dst](#dst)'合成方法。 |
|
100 |
叠加图像在空白画布上。 |
相当于'[Src](#src)'合成方法。 |
|
100x100 |
仅将两幅图像相加。 |
相当于'[Plus](#plus)'合成方法。 |
|
50 |
两幅图像的平均值。这相当于对两幅图像使用"[-evaluate-sequence mean](https://imagemagick.org/command-line-options/#average)"图像序列运算符。(另见图像平均化) |
Blend 与 Dissolve 的对比
虽然Dissolve和Blend都能让图像变得半透明,但"[-dissolve](https://imagemagick.org/command-line-options/#dissolve)"是使用'[Over](#over)'来合成图像,而"[-blend](https://imagemagick.org/command-line-options/#blend)"是使用'[Plus](#plus)'来合并图像。这看起来差别不大,但其实非常重要,因为它决定了这两种合成方法如何处理未被叠加的图像部分,或叠加图像为透明的区域。举例来说。
magick dragon_sm.gif star.gif -alpha on \
-compose dissolve -define compose:args=50 \
-gravity South -composite dissolve_50.png
magick dragon_sm.gif star.gif -alpha on \
-compose blend -define compose:args=50 \
-gravity South -composite blend_50.png
请注意,即使在混合(Blend)图像中,'dragon'背景中未叠加的部分是半透明的,但星星所在区域在两幅图像中都是完全不透明的,并且包含相同的颜色结果!也就是说,对于两幅图像都完全不透明的区域,只要你让IM自动计算出合适的第二个'{_dst_percent_}'参数,结果同样会是完全不透明并得到相同的结果。举例来说,这里我将'dragon'图像与内置的'rose'图像合并。我把两幅图像裁剪成相同大小,这样两幅完全不透明的图像才能完全覆盖彼此。
magick dragon_sm.gif rose: -crop 70x46+0+0 +repage -alpha on \
-compose dissolve -define compose:args=50 \
-gravity South -composite dissolve_50_opaque.png
magick dragon_sm.gif rose: -crop 70x46+0+0 +repage -alpha on \
-compose blend -define compose:args=50 \
-gravity South -composite blend_50_opaque.png
如果你比较这两幅图像,会发现它们完全相同。总结来说,对于任何完全不透明的图像,Dissolve(仅按透明度百分比叠加叠加图像的 over 合成)与 Blend(对两幅图像按各自百分比加权相加)产生的结果是相同的。只有当其中一幅或两幅图像含有透明度时,这两种方法才会出现差异。
使用 Blend 修改单张图像
| Blend 本质上是一个“插值函数”,或者说“加权平均”,可以让你以受控的线性方式组合两幅完全不透明的图像。也就是说,30% 的源图像加上 70% 的背景图像,生成一幅新的 100% 不透明图像。但它能做的不仅仅是组合两幅图像。它还可以用来提亮、设置对比度、饱和度、上色,甚至锐化某张特定图像。关于 blend 这种用法的进一步讨论,可以参见 BugBear bugbear@papermule.co.uk 在网上发布的一篇文档 Image Processing by Interpolation and Extrapolation,它是 Grafica Obscura(该站点无法从外部直接链接)上那篇文档的副本。推荐阅读该文档以进一步了解此函数的用法。 | 外推(extrapolation)能力是在 IM v6.3.5-10 中被加入到 "[-blend](https://imagemagick.org/command-line-options/#blend)" 操作符的。 |
|---|---|
| 例如,这里我们可以通过将玫瑰图像与同尺寸的纯黑图像混合,使其变亮或变暗。 |
magick composite -blend 0 rose: -size 70x46 xc:black -alpha Set blend_dark_0.jpg
magick composite -blend 50 rose: -size 70x46 xc:black -alpha Set blend_dark_50.jpg
magick composite -blend 100 rose: -size 70x46 xc:black -alpha Set blend_dark_100.jpg
magick composite -blend 150 rose: -size 70x46 xc:black -alpha Set blend_dark_150.jpg
magick composite -blend 200 rose: -size 70x46 xc:black -alpha Set blend_dark_200.jpg
![[IM Output]](../static/img/compose/blend_dark_0.jpg)
0% | ![[IM Output]](../static/img/compose/blend_dark_50.jpg)
50% | ![[IM Output]](../static/img/compose/blend_dark_100.jpg)
100% | ![[IM Output]](../static/img/compose/blend_dark_150.jpg)
150% | ![[IM Output]](../static/img/compose/blend_dark_200.jpg)
200%
---|---|---|---|---
正如 Blend 合成方法 的任何用法一样,0% 得到的是“目标”图像,而 100% 时得到的是原始“源”图像本身不作改动。这里更有趣的是混合与外推得到的图像。类似地,与一幅纯灰色图像混合可以让你调整任意图像的对比度。
magick composite -blend 0 rose: -size 70x46 xc:'#808080' -alpha Set blend_gray_0.jpg
magick composite -blend 50 rose: -size 70x46 xc:'#808080' -alpha Set blend_gray_50.jpg
magick composite -blend 80 rose: -size 70x46 xc:'#808080' -alpha Set blend_gray_80.jpg
magick composite -blend 100 rose: -size 70x46 xc:'#808080' -alpha Set blend_gray_100.jpg
magick composite -blend 120 rose: -size 70x46 xc:'#808080' -alpha Set blend_gray_120.jpg
magick composite -blend 150 rose: -size 70x46 xc:'#808080' -alpha Set blend_gray_150.jpg
![[IM Output]](../static/img/compose/blend_gray_0.jpg)
0% | ![[IM Output]](../static/img/compose/blend_gray_50.jpg)
50% | ![[IM Output]](../static/img/compose/blend_gray_80.jpg)
80% | ![[IM Output]](../static/img/compose/blend_gray_100.jpg)
100% | ![[IM Output]](../static/img/compose/blend_gray_120.jpg)
120% | ![[IM Output]](../static/img/compose/blend_gray_150.jpg)
150%
---|---|---|---|---|---
这里我将图像与其灰度版本混合,从而可以控制颜色的饱和度。
magick rose: -type grayscale rose_gray.png
magick composite -blend 0 rose: rose_gray.png -alpha Set blend_color_0.jpg
magick composite -blend 50 rose: rose_gray.png -alpha Set blend_color_50.jpg
magick composite -blend 100 rose: rose_gray.png -alpha Set blend_color_100.jpg
magick composite -blend 150 rose: rose_gray.png -alpha Set blend_color_150.jpg
magick composite -blend 200 rose: rose_gray.png -alpha Set blend_color_200.jpg
![[IM Output]](../static/img/compose/blend_color_0.jpg)
0% | ![[IM Output]](../static/img/compose/blend_color_50.jpg)
50% | ![[IM Output]](../static/img/compose/blend_color_100.jpg)
100% | ![[IM Output]](../static/img/compose/blend_color_150.jpg)
150% | ![[IM Output]](../static/img/compose/blend_color_200.jpg)
200%
---|---|---|---|---
这里我将玫瑰图像与其模糊版本进行混合,在插值时产生柔化模糊,在从模糊形式外推时产生反锐化。
magick rose: -blur 0x5 rose_blurred.png
magick composite -blend 0 rose: rose_blurred.png -alpha Set blend_blur_0.jpg
magick composite -blend 50 rose: rose_blurred.png -alpha Set blend_blur_50.jpg
magick composite -blend 100 rose: rose_blurred.png -alpha Set blend_blur_100.jpg
magick composite -blend 150 rose: rose_blurred.png -alpha Set blend_blur_150.jpg
magick composite -blend 200 rose: rose_blurred.png -alpha Set blend_blur_200.jpg
![[IM Output]](../static/img/compose/blend_blur_0.jpg)
0% | ![[IM Output]](../static/img/compose/blend_blur_50.jpg)
50% | ![[IM Output]](../static/img/compose/blend_blur_100.jpg)
100% | ![[IM Output]](../static/img/compose/blend_blur_150.jpg)
150% | ![[IM Output]](../static/img/compose/blend_blur_200.jpg)
200%
---|---|---|---|---
水印选项 - 合成方法 'Modulate'
"[-watermark](https://imagemagick.org/command-line-options/#watermark)" 合成选项或 "modulate" 合成方法,用于在 HSB 空间中对图像颜色进行_调制/改变_处理,以达到版权保护的目的。
**magick composite -watermark {_brightness_}[x{_saturation_}] overlay bgnd result \
magick bgnd overlay -compose modulate \
-define compose:args={_brigthness_}[,{_saturation_}] \
-composite result
**
'overlay' 图像是一张带有 alpha 蒙版的黑白图像,用于按给定的 'brightness ' 百分比使目标图像变亮/变暗。 'brightness ' 为 '0' 时不改变图像亮度,而值为 '100' 时则用叠加图像的亮度替换目标图像的亮度。也就是说,如果叠加图像为黑色,则目标图像变为黑色;如果为白色,则目标图像的颜色将完全饱和。 'saturation ' 默认值为 '100',产生最大的颜色饱和度。若设为 '0',被蒙版覆盖的区域将被去饱和为黑白色。下面是使用不同参数得到的结果表格... |
magick composite -watermark {_argument_} -gravity South \
sphinx.gif cyclops.gif {_result_}
对图像进行轻度水印处理的一个较好取值是 brightness 约为 15 到 30 百分比。以下是特定 "[-watermark](https://imagemagick.org/command-line-options/#watermark)" 参数的特殊情况... 0 |
完全不改变目标图像。 | |
|---|---|---|
100 |
当叠加图像为黑色时目标图像变为黑色,为白色时则变为完全饱和的色相 | |
0x0 |
被蒙版覆盖的叠加区域被去饱和为灰阶 | |
100x0 |
灰阶叠加图像仅以 '[ATop](#atop)' 方式叠加在目标图像之上。 |
|
| 其他水印技术请参见使用图像添加水印。 |
使用合成蒙版限制合成区域
"magick composite" 命令和 "[-composite](https://imagemagick.org/command-line-options/#composite)" 操作符还可以接受第三张蒙版图像,用于限制受 "[-compose](https://imagemagick.org/command-line-options/#compose)" 方法影响的区域。例如,给定两张图像和一张_蒙版_图像,你可以按该蒙版所定义的方式,将_源_图像的一部分叠加到_背景_图像上。但请注意,_背景_图像仍然决定了最终结果图像的尺寸。
magick composite tile_water.jpg tile_aqua.jpg moon_mask.gif mask_over.jpg
_蒙版_图像被视为目标图像的一部分,用于定义目标图像中哪些部分可以被 alpha 合成的结果所修改。也就是说,白色部分可以被修改,而黑色部分(以及蒙版图像之外的部分)则保持不变。遗憾的是,虽然 "[-gravity](https://imagemagick.org/command-line-options/#gravity)" 和 "[-geometry](https://imagemagick.org/command-line-options/#geometry)" 设置可以让你重新定位_源_图像,但_蒙版_图像并不会被重新定位,而是始终与_目标_图像保持对齐。所以让我们把这一点说清楚...
蒙版与原始背景图像对齐。
任何 gravity/geometry 设置都不会应用于它。
这意味着,如果我想重新定位蒙版,就需要在蒙版图像中添加适量的黑色行和列来扩大它。参见拼接,添加像素的行和列。例如,下面是一个 "magick" 版本(源图像与背景图像参数互换),其中蒙版图像已被调整,以便相对于背景图像移动它。 |
magick tile_aqua.jpg tile_water.jpg \
\( -background black -splice 10x25+0+0 moon_mask.gif \) \
-composite mask_offset.jpg
![[IM Output]](../static/img/compose/mask_offset.jpg)
请记住,"magick"命令的"[-composite](https://imagemagick.org/command-line-options/#composite)"操作符首先指定目标或背景图像。其效果就像给蒙版一个'+10+25'的偏移量,但源图像和背景图像都不会移动。如果你想让蒙版与源图像对齐,最好单独对源图像做蒙版处理(使用'[Copy_Opacity](#copyopacity)'或其他技术)。然后你就可以把处理结果放到背景上,而不会有对齐问题。下面是一个类似的例子,但这次我使用了一个与背景图像大小相同的渐变蒙版,把两幅图像融合在一起,产生一种"浅滩"效果。 |
magick tile_aqua.jpg tile_water.jpg -size 94x94 gradient: \
-composite water_shallows.jpg
![[IM Output]](../static/img/compose/water_shallows.jpg)
这提供了一种叠加两幅图像的简单方法。参见叠加照片。
合成蒙版与透明度
从上面的内容你可能会以为,使用三图合成蒙版与使用'[Copy_Opacity](../static/img/compose/copyopacity)'来设置叠加图像的透明度、然后将其合成到背景图像上非常相似。对于没有任何透明度的图像(比如上面的例子)确实如此。但事情并非如此简单。首先,蒙版是与目标图像绑定的,而不是与源图像绑定,所以它不受偏移或重力设置的影响。此外,与'[Copy_Opacity](../static/img/compose/copyopacity)'不同,蒙版图像被纯粹当作灰度图像处理。IM 会忽略蒙版可能具有的所有alpha透明度。因此你_不需要_担心在蒙版图像中"关闭Alpha 通道"。最后,蒙版的作用是限制被修改的区域,这与仅仅对源图像做蒙版处理截然不同。对于简单的'[Over](../static/img/compose/over)'合成来说,这相当于把蒙版与源图像中的任何透明度相乘,以限制叠加的范围。因此对于完全不透明的源图像,你可以把它理解为源图像的透明度。例如,像平常一样叠加两个圆,然后再用一个蒙版叠加它们,限制目标图像被改变的区域。
magick -size 60x60 xc:none -fill red -draw 'circle 35,21 35,3' m_src.png
magick -size 60x60 xc:none -fill blue -draw 'circle 21,39 24,57' m_bgnd.png
magick -size 60x60 xc: -draw 'polygon 0,59 59,0, 0,0' m_mask.png
magick composite m_src.png m_bgnd.png m_over.png
magick composite m_src.png m_bgnd.png m_mask.png m_over_masked.png
其结果相当于红色圆圈图像经过给定的灰度蒙版处理后,再叠加到目标图像上。不过对于其他类型的 alpha 合成方法,你最好把蒙版理解为限制效果作用的区域,而不是源图像的透明度蒙版。这里我使用了'[Src](../static/img/compose/src)'方法,用源图像的内容替换目标图像中被蒙版覆盖的区域。 |
magick composite m_src.png m_bgnd.png m_mask.png -compose Src m_src_masked.png
![[IM Output]](../static/img/compose/m_src_masked.png)
如你所见,只有定义了蒙版的区域才会被 alpha 合成的结果实际替换。如果蒙版只是用来修改源图像的透明度,上面的结果就只会显示源图像,而不会显示背景图像的任何内容。
FUTURE: Using masked composition to overlay an object in front of a
backdrop, but behind some foreground object. Also develop an animated example,
of something being obscured by foreground objects in the destination.
| _以上内容涉及一个长期存在的重大缺陷,即当源图像或叠加图像带有透明度、或者尝试使用除'[Over](#over)'合成方法之外的其他 alpha 合成方式时,合成蒙版会出现问题。详见合成蒙版缺陷。
_
---|---
使用图像平铺进行合成
"[-tile](https://imagemagick.org/command-line-options/#tile)"设置在"magick composite"中,与"magick"或"magick montage"中的同名设置大不相同。如果给出该设置,意味着要将_源_图像平铺到_背景_图像上。例如,下面我们将一个"彩色星星"平铺到netscape颜色映射图像上…… |
magick composite -tile star.gif netscape: tile.gif
![[IM Output]](../static/img/compose/tile.gif)
合成平铺的一个常见用途是,在把图像发布到网上之前,给图像平铺半透明的版权声明或其他提示信息。相关示例参见用文字加水印最后的示例。请注意,该设置本质上(至少目前)是不带参数的。它只是最终"magick composite"操作的一个布尔开关标志。因此你不能用它来平铺_背景_图像,因为那样 IM 就无法用背景图像来确定结果的最终尺寸。不过你可以改用'[Dst_Over](#dstover)'把一幅图像平铺在另一幅图像下面。 |
magick -background none -pointsize 36 label:'Tile Under' png:- |\
magick composite -tile bg.gif - -compose Dst_Over tile_under.gif
![[IM Output]](../static/img/compose/tile_under.gif)
许多数学运算符也具有可交换性,意味着交换源图像和目标图像不会影响结果(最终图像尺寸除外)。目前在"magick"命令中还没有简单的方法来进行平铺 alpha 合成。这有点遗憾,因为这样可以让使用内存中已有的图像进行平铺变得比现在容易得多。使用"magick"进行合成平铺的基本技巧是克隆原始图像,然后使用平铺画布中给出的方法之一对其进行平铺。例如... |
magick -gravity center -pointsize 32 -font Corsiva \
label:'Tile White\nBackgrounds' -bordercolor white -border 5 \
\( -clone 0 -tile tile_aqua.jpg -draw "color 0,0 reset" \) \
-compose Multiply -composite tile_convert.gif
![[IM Output]](../static/img/compose/tile_convert.gif)
上面的例子使用数学合成方法"[Multiply](#multiply)"替换了标签的"白色背景"。另请参阅使用图像蒙版、数学合成。
特殊合成方法
Mathematics(用户自定义数学合成方法)
这种合成方法接受 4 个数值,允许用户定义许多不同的数学合成方法。这四个参数"A"、"B"、"C"和"D"定义了如下公式...
A*Sc*Dc + B*Sc + C*Dc + D
其中"Sc"是源图像或叠加图像,"Dc"是背景图像或目标图像。必须提供全部四个值。例如,我们可以生成等价于"[Multiply](#multiply)"合成方法的效果,所用取值为"1,0,0,0"。
magick gradient_dst.png gradient_src.png \
-compose Mathematics -define compose:args='1,0,0,0' -composite \
mathematics_multiply.png
![[IM Output]](../static/img/compose/gradient_src.png)
源图像 | | ![[IM Output]](../static/img/compose/gradient_dst.png)
目标图像 | | ![[IM Output]](../static/img/compose/mathematics_multiply.png)
结果
---|---|---|---|---
同样地,通过查找或推导出所需的公式,你可以生成其他合成方法,例如... [Screen](#screen): 1-(1-Sc)*(1-Dc) => -Sc*Dc + Sc + Dc => -1,1,1,0 |
magick gradient_dst.png gradient_src.png \
-compose Mathematics -define compose:args='-1,1,1,0' -composite \
mathematics_screen.png
![[IM Output]](../static/img/compose/mathematics_screen.png)
或者"[LinearLight](#linearlight)",它可以直接用参数"0,2,1,-1"定义... |
magick gradient_dst.png gradient_src.png \
-compose Mathematics -define compose:args='0,2,1,-1' -composite \
mathematics_linearlight.png
![[IM Output]](../static/img/compose/mathematics_linearlight.png)
同样地,你还可以生成其他合成方法,例如... 合成方法 | Mathematics 参数
---|---
[Multiply](#multiply) | 1,0,0,0
[Screen](#screen) | -1,1,1,0
[Exclusion](#exclusion) | 0,1,1,-1
[Linear_Dodge](#lineardodge) | 0,1,1,0
[Linear_Burn](#linearburn) | 0,1,1,-1
[Linear_Light](#linearlight) | 0,2,1,-1
其他合成方法需要用到平方、平方根、除法,甚至多个特殊的分段函数和条件判断,这使得它们无法用这种方法所提供的简单平滑多项式函数来定义。你也可以创建新的合成方法,例如作为LinearLight的扩展替代方案... |
magick gradient_dst.png gradient_src.png \
-compose Mathematics -define compose:args='0,1,1,-0.5' \
-composite mathematics_linearlight_2.png
![[IM 输出]](../static/img/compose/mathematics_linearlight_2.png)
这种自定义合成方式作为一种添加带偏移的渐变(例如正弦波)的手段十分重要。或者是另一种可用于"光照效果"的变体... |
magick gradient_dst.png gradient_src.png \
-compose Mathematics -define compose:args='0,1,.5,-.25' \
-composite mathematics_linearlight_3.png
![[IM 输出]](../static/img/compose/mathematics_linearlight_3.png)
数学合成方法对于让你实现某些特殊类型的渐变上的数学运算尤为重要,若用多个单独步骤来实现,这些运算会非常复杂。 | "[Mathematics](#mathematics)"合成方法是在 IM 6.5.4-3 版本中加入的。目前仅能通过"-compose"操作符使用。由于它需要参数,因此无法通过"magick composite"命令使用。
---|---
Change_Mask(将相似像素变为透明)
这是一种不寻常的方法,它只会将目标图像中的特定像素变为完全透明。也就是说,根据当前的模糊因子设置,目标图像中与给定源图像相匹配的像素会被处理。例如,这可以用来为叠加到复杂(但差异很大)背景上的图像重新加入透明度。举个例子,这正是 Jesper Eije 所遇到的问题...
magick overlay_figure.gif overlay_bgnd.gif \
-compose ChangeMask -composite overlay_removed.png
很简单。请注意,由于 JPEG 图像的颜色由于该文件格式的有损性质,经常会出现轻微的颜色变化,因此需要设置一个较小的模糊因子才能匹配非常相近的颜色。此外,如果图像中被更改的部分恰好与背景颜色或图案相匹配,那么在生成的图像或蒙版中就会出现"漏洞",因此在对非常相似的图像使用此方法时务必谨慎。通过交换这两张图像,即把背景图像作为目标图像,你可以提取出背景中被叠加图像替换或修改的部分。 |
magick overlay_bgnd.gif overlay_figure.gif \
-compose ChangeMask -composite overlay_changed.png
![[IM 输出]](../static/img/compose/overlay_changed.png)
请注意,结果只是原始背景图像的一个透明形状蒙版,其中相似的像素只是被清除为透明。它不会尝试生成部分透明度或改变颜色,因此在原始叠加图像与背景颜色融合的地方,可能会留下一圈颜色略有不同的"光晕"。由于此合成方法只会将像素"清除"为完全透明,因此结果图像总是会被添加一个 alpha 通道。然而,目标图像的颜色不会像大多数其他 alpha 合成方法那样被清除。因此,你可以对 alpha 通道取反,从而得到未改变的颜色。 |
magick overlay_figure.gif overlay_bgnd.gif -compose ChangeMask -composite \
-channel A -negate overlay_unchanged.png
![[IM 输出]](../static/img/compose/overlay_unchanged.png)
在这种情况下,输入图像的顺序并不重要,除非设置了较大的模糊因子。请记住,颜色来自目标图像,而两张图像之间的差异定义了最终的形状蒙版。有关这些问题的更多信息,请参阅背景移除。其结果的直接实用性通常有限。不过,它可以用来生成图像之间变化的位图蒙版(因此得名)。 | _"[ChangeMask](#changemask)"合成方法是在 IM v6.3.4 中加入的,用于为 GIF 动画提供一种优化透明度的方法。没有其他现有的合成方法能够在不结合 3 种或更多合成方法的情况下满足所需的要求。具体来说,就是透明度优化所需要的布尔(或模糊因子阈值)要求。
然而,其结果本身极为实用,因此被公开供用户直接使用,也由此定义了这个相当复杂的合成方法的名称。_
---|---
图像映射效果方法
还有几种特殊方法,严格来说它们并不属于合成方法。这些方法不是逐像素直接合并两张图像,而是将源图像或叠加图像作为一种特殊的控制映射,用于实现某种更大规模的效果。虽然这些方法本身相对简单,但它们的用法却相当复杂,因此各自拥有专门的示例章节。参见图像映射效果。这些特殊方法包括... "Blur"方法提供了一种以不同方式逐像素模糊图像的手段。它可以生成各种各样的自定义图像模糊效果。详情请参阅可变模糊映射。 另一方面,"Displace"方法提供了绝对和相对像素查找位移技术,它不仅能生成特定的图像扭曲方法,还能实现玻璃、镜片和涟漪等效果。详情请参阅扭曲与位移映射。
![[IM Output]](../static/img/compose/convert_over.gif)
![[IM Output]](../static/img/compose/compose_under_tiled.jpg)
![[IM Output]](../static/img/images/hand_point.gif)
![[IM Output]](../static/img/compose/compose_expand.gif)
![[IM Output]](../static/img/compose/compose_clear_limited.gif)
![[IM Output]](../static/img/images/text_scan.png)
![[IM Output]](../static/img/compose/text_scan_norm.png)
![[IM Output]](../static/img/compose/text_scan_divide.png)
![[IM Output]](../static/img/compose/compose_R.png)
![[IM Output]](../static/img/compose/compose_G.png)
![[IM Output]](../static/img/compose/compose_B.png)
![[IM Output]](../static/img/compose/compose_plus_RG.png)
![[IM Output]](../static/img/compose/compose_plus_RB.png)
![[IM Output]](../static/img/compose/compose_plus_GB.png)
![[IM Output]](../static/img/compose/compose_plus_RGB.png)
![[IM Output]](../static/img/compose/compose_add.png)
![[IM Output]](../static/img/compose/gradient_diagonal.png)
![[IM Output]](../static/img/compose/black_n_white.gif)
![[IM Output]](../static/img/compose/compose_negate.gif)
![[IM Output]](../static/img/compose/gradient_op_exclusion.png)
![[IM Output]](../static/img/img_photos/flower_sm.jpg)
![[IM Output]](../static/img/compose/flower_softglow.jpg)
![[IM Output]](../static/img/compose/red_gradient.png)
![[IM Output]](../static/img/compose/blue_gradient.png)
![[IM Output]](../static/img/compose/lighten_by_value.png)
![[IM Output]](../static/img/compose/lighten_intensity.png)
![[IM Output]](../static/img/compose/circle_left.gif)
![[IM Output]](../static/img/compose/circle_right.gif)
![[IM Output]](../static/img/compose/circle_union.gif)
![[IM Output]](../static/img/compose/circle_intersection.gif)
![[IM Output]](../static/img/compose/circle_disjunction.gif)
![[IM Output]](../static/img/compose/circle_complement.gif)
![[IM Output]](../static/img/compose/gradient_op_hardlight.png)
![[IM Output]](../static/img/compose/gradient_op_linearlight.png)
![[IM Output]](../static/img/compose/gradient_op_vividlight.png)
![[IM Output]](../static/img/compose/gradient_op_pinlight.png)
![[IM Output]](../static/img/compose/gradient_op_lineardodge.png)
![[IM Output]](../static/img/compose/gradient_op_linearburn.png)
![[IM Output]](../static/img/compose/circle_subtract.gif)
![[IM Output]](../static/img/compose/gradient_op_colordodge.png)
![[IM Output]](../static/img/images/star.gif)
![[IM Output]](../static/img/images/dragon_sm.gif)
![[IM Output]](../static/img/compose/dissolve_montage.jpg)
![[IM Output]](../static/img/compose/blend_montage.jpg)
![[IM Output]](../static/img/compose/dissolve_50.png)
![[IM Output]](../static/img/compose/blend_50.png)
![[IM Output]](../static/img/compose/dissolve_50_opaque.png)
![[IM Output]](../static/img/compose/blend_50_opaque.png)
![[IM Output]](../static/img/images/sphinx.gif)
![[IM Output]](../static/img/images/cyclops.gif)
![[IM Output]](../static/img/compose/wmark_montage.jpg)
![[IM Output]](../static/img/images/tile_water.jpg)
![[IM Output]](../static/img/images/tile_aqua.jpg)
![[IM Output]](../static/img/compose/mask_over.jpg)
![[IM Output]](../static/img/compose/m_src.png)
![[IM Output]](../static/img/compose/m_bgnd.png)
![[IM Output]](../static/img/compose/m_over.png)
![[IM Output]](../static/img/compose/m_mask.png)
![[IM Output]](../static/img/compose/m_over_masked.png)
![[IM 输出]](../static/img/images/overlay_figure.gif)
![[IM 输出]](../static/img/images/overlay_bgnd.gif)
![[IM 输出]](../static/img/compose/overlay_removed.png)