ImageMagick 示例 -- 杂项
- ImageMagick 示例前言与索引
- 插值(像素间颜色查询)
- 简单插值方法
- 双线性、网格、Catrom、样条
- 背景上的插值
- 旋转直线的插值
-
虚拟像素(超出图像范围的颜色查询)
-
Edge、Tile、Mirror、Transparent、Black、Gray、White、Background、
HoriziontalTile、HoriziontalTileEdge、VerticalTile、VerticalTileEdge、
CheckerTile、Random、Dither - 虚拟像素与无穷远
- 虚拟像素颜色
- 虚拟像素示例
-
随机纯色斑点 Annotate 参数用法 Splice:创建新的图像运算符 Border、Frame 与 BorderColor 的使用 List 运算符测试 本页收录了用于测试 ImageMagick 各方面特性的示例,但这些内容并不适合放入其他示例页面的讨论中(至少形式上不合适)。本页还包含一些表格,展示特定 IM 运算符在不同版本下的参数结果。不过其他人也做过类似的事情,除非我有新内容可以补充,否则不会进一步展开。
像素插值,或称像素间颜色查询
“[-interpolate](https://imagemagick.org/command-line-options/#interpolate)”设置用于在源图像中查询颜色时,若该“查询点”恰好落在源图像像素之间的情况。这在多种图像操作中都会用到,例如“[-fx](https://imagemagick.org/command-line-options/#fx)”(DIY 特效运算符)、“[-distort](https://imagemagick.org/command-line-options/#distort)”(通用图像畸变运算符),以及其他相关运算符,如环形畸变。简单来说,“插值”告诉 IM 在从图像中进行直接颜色查询时,若该点与图像中实际像素不完全对应,而是落在像素之间的空隙中,应如何解读。例如,如果你查询像素位置3,4处的颜色,你应该得到该像素的精确颜色。但如果你查询的是图像中3.23,4.75这一点的颜色呢?应该得到3,4还是3,5处的像素颜色?又或者是周围像素颜色的某种混合,如果是这样,这些颜色应该如何混合在一起?_像素插值_定义了 ImageMagick 在(以像素坐标表示的)浮点位置查询单个颜色时应执行的操作。插值在某些方面类似于像素重采样,例如重采样滤镜所提供的那种。本质区别在于,重采样具有“比例”、“区域”或可变的“窗口”,会从中返回一个代表该区域内所有像素的颜色。而插值不涉及“比例”,只有单一的查询“点”,以及围绕该点的一个固定大小的“区域”,用来确定该点应使用的颜色。当然,大多数区域重采样算法在重采样区域缩小到最小可用“窗口”时,往往会退化为插值方法,这在图像放大或上采样时自然会发生。这也是为什么插值滤镜和高斯模糊滤镜在放大图像时往往效果更好。插值基本上是一种较低层次的采样形式,通常用于你想要对“该用什么颜色”这一问题给出简单快速答案的场合。
简单插值方法
这些方法都很直接、简单,力求以尽量少的处理来返回“点插值”所需的颜色。最简单的是“Nearest”和“Integer”,它们只会从源图像中原样挑选出一个像素颜色,不进行任何混合或其他调和处理。这保留了图像原始的颜色值,但代价是产生锯齿效果,通常图像看起来也不够平滑。 |
自 IM v6.7.6-2 起,你可以用“Nearest”作为“Nearest-Neighbour”插值设置的简写。 |
|---|---|
这两者非常相似,区别仅在于查询坐标从源图像中提取的是哪个像素。具体来说,“Integer”只是简单地将查询点向下取整来选取像素,其结果是整体向右下方偏移半个像素。它通常仅用于源图像的简化“缩放”。而“Nearest”则会选取距离浮点查询坐标最近的像素,因而产生更准确的结果。“Blend”会根据与采样点的距离,将最近的1、2或4个像素混合(平均)在一起。其结果是原始像素颜色依然存在,但尺寸减半,而混合色的棋盘格图案则填充在其间的空隙中(见下方示例)。“Average”则永远不会真正产生精确匹配的颜色,而是始终混合周围的4个像素以产生局部平均值。这在某些颜色查询场景中会很有用。“Average4”也可以作为该插值方法的别名使用。“Average9”与之类似,但会对采样点周围最近的9个像素取平均,产生较模糊的结果。“Average16”会对采样点周围最近的16个像素取平均,产生极其模糊的结果。以下是各种简单插值方法在放大一小组彩色像素或单个白色像素时的效果汇总。原始图像看起来就像“Nearest”的结果,只是小得多。 |
for method in integer nearest blend average average9 average16 ; do
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-bordercolor black -border 1 \
-filter point -interpolate $method \
+distort SRT 20,0 ip_color_${method}.jpg
magick xc: -bordercolor black -border 2 \
-filter point -interpolate $method \
+distort SRT 16,0 ip_pixel_${method}.jpg
done
| 在 IM v6.7.7-6 之前,“Average”实际上等同于现在的“Average16”。另外两种平均类插值方法,以及“Blend”和“Background”都是在此时新增的。
---|---
另外还提供了一种简单插值方法,即“Background”,它对源图像的任何“采样”都只会简单地返回当前的背景色。从许多方面来看,这相当没有实用价值,因为通常你最终只会得到一张纯色空白图像。它的主要用途是作为更复杂重采样函数的检查手段,例如重采样失败的情况——当 EWA 重采样滤镜(通常由通用畸变运算符使用)在重采样时未能在其“支持区域”或重采样区域内找到任何像素时,会回退到插值查询。通过将插值设置为“Background”,并将背景色设置为某种醒目的颜色(例如“red”),你就可以在结果图像中寻找这些像素,从而找出由于某种原因导致重采样“失败”或“未命中任何源图像像素”的位置。这通常是由于支持区域设置过小,或是调整专家级滤镜选项所致。 未来展望:未来可能会为插值区域增加“random”(随机选取)选项。这对于制作花哨的插值效果可能会很有用!
双线性(Bilinear)
“Bilinear”(即线性插值)是默认的插值方法,也可能是通过组合查询点或采样点周围像素颜色来获得真正插值结果的最简单方式之一。下图说明了双线性插值的工作原理。
![[示意图]](../static/img/img_diagrams/bilinear_interpolation.jpg)
也就是说,它只是沿正交方向连接直线,以确定给定采样点的颜色。其结果也等价于在调整大小时使用三角形重采样滤镜。 |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -fx 'v.p{i/(w-1),j/(h-1)}' \
interpolate_bilinear.jpg
magick \( xc:white xc:black +append \) \
\( xc:black xc:white +append \) -append \
-size 100x100 xc: +swap -fx 'v.p{i/(w-1),j/(h-1)}' \
interpolate_saddle.jpg
![[IM 输出]](../static/img/misc/interpolate_saddle.jpg)
最后这张图展示了线性渐变是如何沿着四个已知点之间的边形成的,然后在这些边之间再形成第二重线性渐变。也就是说,周围像素之间的颜色是通过水平和垂直方向的线性渐变生成的。这反过来会产生一种弯曲的二维渐变,通常被称为“鞍形”(saddle),因为它在两个相对的角上被抬高,而在另外两个相对的角上被压低。你甚至可以用这种方法更直接地生成一个45度角的线性渐变,但需要为对角线上相对的两个角指定中间色。 |
magick \( xc:blue xc:navy +append \) \
\( xc:navy xc:black +append \) -append \
-size 100x100 xc: +swap -fx 'v.p{i/(w-1),j/(h-1)}' \
interpolate_45linear.jpg
![[IM 输出]](../static/img/misc/interpolate_45linear.jpg)
这一默认插值方法最重要的特点在于,图像正中心的像素始终是四个角颜色的平均值,边缘处呈现完美的线性渐变,而四个角上的颜色则精确匹配。
网格(Mesh)
“[-interpolate](https://imagemagick.org/command-line-options/#interpolate)”中的“Mesh”设置是“[Bilinear](#bilinear)”插值的一种变体。“Bilinear”会生成一个三维弯曲曲面,而“Mesh”则被设计为将像素间区域拆分为两个平面三角形。该区域被划分为两个三角形所依据的对角线,是连接两个“最接近”的角颜色的那条对角线。 |
有关“Mesh”算法的详细信息,请参阅论文《基于像素级数据依赖三角剖分的图像插值》。 |
|---|---|
| 例如,让我们使用与上面相同的一组角颜色。 |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Mesh \
-fx 'v.p{i/(w-1),j/(h-1)}' interpolate_tri-mesh.jpg
![[IM 输出]](../static/img/misc/interpolate_tri-mesh.jpg)
可以看到,'Mesh' 算法生成的颜色插值结果几乎和 '[Bilinear](#bilinear)' 完全一样。不过如果我们交换黄色和青色的位置.. |
magick \( xc:red xc:blue +append \) \
\( xc:cyan xc:yellow +append \) -append \
-size 100x100 xc: +swap -interpolate Mesh \
-fx 'v.p{i/(w-1),j/(h-1)}' interpolate_tri-mesh2.jpg
![[IM 输出]](../static/img/misc/interpolate_tri-mesh2.jpg)
这一次,'Mesh' 算法判定 'blue' 和 'cyan' 这两种颜色是最接近的两个角,于是在这两个角之间沿对角线方向创建了一个线性渐变。其余的颜色则从这条线到另外两个角,形成一个简单的平面三角形渐变。这看起来可能是一种不寻常的插值方式,但该方法能确保当彩色图像只是被轻微缩放、旋转或错切时,锐利的边界依然保持锐利。事实上,自适应缩放 操作("[-adaptive-resize](https://imagemagick.org/command-line-options/#adaptive-resize)")正是利用这一特性,在小幅缩放图像时减少结果的过度模糊。例如,如果只有一个角是 'white'(白色),'mesh' 会认为这里发现了一条边缘,并调整插值后的颜色以突出这条边缘。 |
magick \( xc:black xc:black +append \) \
\( xc:white xc:black +append \) -append \
-size 100x100 xc: +swap -interpolate Mesh \
-fx 'v.p{i/(w-1),j/(h-1)}' interpolate_tri-mesh3.jpg
![[IM 输出]](../static/img/misc/interpolate_tri-mesh3.jpg)
当然,如果这些颜色本身能产生相当一致的渐变,那么 'mesh' 插值同样也会生成相当一致的渐变。 |
magick \( xc:blue xc:navy +append \) \
\( xc:black xc:black +append \) -append \
-size 100x100 xc: +swap -interpolate Mesh \
-fx 'v.p{i/(w-1),j/(h-1)}' interpolate_tri-mesh4.jpg
![[IM 输出]](../static/img/misc/interpolate_tri-mesh4.jpg)
可以看到,结果是相当合理的渐变,不过仔细看的话,还是能看出两个三角形拼接处的对角线痕迹。这种变化不如双线性插值那样平滑(双线性插值其实也算不上真正平滑),但这些方法在缩放或扭曲图像时也不会刻意保留锐利边缘。
Catrom (Catmull-Rom)
"[-interpolate](https://imagemagick.org/command-line-options/#interpolate)" 设置为 'Catrom'(通常被不太严谨地称为 'BiCubic' 插值)时,在确定某一点的查找颜色上要复杂得多。它不仅仅查看像素间区域四个角上的颜色,还会进一步查看这些最近邻像素之外的颜色,即采样点周围 4x4 区域共 16 个像素。基本上,它会对涉及的整个区域拟合一条曲线,以确定要使用的最佳整体颜色。下面这张图应该能更好地说明这个过程……
![[示意图]](../static/img/img_diagrams/bicubic_interpolation.jpg)
下面是我们标准的四种颜色所得到的插值结果。 |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Catrom \
-fx 'v.p{i/(w-1),j/(h-1)}' interpolate_catrom.jpg
![[IM 输出]](../static/img/misc/interpolate_catrom.jpg)
上面这张图看起来可能与 '[Bilinear](#bilinear)' 插值非常相似,但其结果使用的是更平滑的混合曲线,而不是直线,来生成插值颜色。不过这张图并没有展示周围其他像素对这四个最近邻像素的影响。要看到这一点,我们需要观察稍大一些的区域。在这个(非常小的)具体示例中,周围的像素由 Virtual Pixel(虚拟像素)设置控制。
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Catrom -virtual-pixel edge \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' interpolate_catrom_edge.jpg
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Catrom -virtual-pixel White \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' interpolate_catrom_white.jpg
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Catrom -virtual-pixel Black \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' interpolate_catrom_black.jpg
| 在真实图像中,Virtual Pixels(虚拟像素)的影响通常只体现在图像最边缘附近的结果上。由于这张图片只有 2 像素宽,上面的示例受到的影响很强烈。在更大、更典型的图像中则不会如此。
---|---
可以看到,曲线受周围颜色的影响很大,这会导致颜色变化非常紧凑锐利,或者根据周围颜色的不同而产生更柔和的混合变化。不过你还会发现,周围像素颜色的剧烈变化,会在小范围内产生该颜色的反色或负片效果。这是一种 振铃伪影,通常只会出现在真实图像中互补色之间极其锐利的边缘处。 | _在颜色变化非常剧烈的边缘上,这种振铃效应可能会被截断,从而产生一行难看的像素。要避免这个问题,可以在与 'RGB' 不同的色彩空间(例如 'Lab' 或 'Luv' 色彩空间)中进行缩放和插值。
关于这个问题的更多信息和示例,请参见 在 LAB 色彩空间中缩放。
_
---|---
| _请注意,'BiCubic'(插值 三次滤镜)实际上指的是一大类滤镜,因此这个名称的含义非常不精确。它目前仍可使用,但已不推荐使用,建议改用更明确的名称。
从 IM v6.7.7-7 之后,'BiCubic' 只是 'Catrom' 的一个别名,而 Catrom 通常被认为是一个不错的“三次插值器”(b=0, c=1/2)。你应该使用 'Catrom' 这个名称而不是 'BiCubic',以便清楚地表明自己使用的是哪种插值方式。
在 IM v6.7.7-7 之前,'BiCubic' 实际使用的是一种极端的 'Cardinal Cubic'(基数三次)滤镜(b=0, c=1),其负向振铃效应过于强烈。这种滤镜已被 'Catrom' 完全取代,不再作为插值函数提供。
在 IM v6.3.5-3 之前,'BiCubic' 是以一种非常模糊的 'Spline' 三次插值器实现的。从这个版本的 ImageMagick 开始,该滤镜被改了名字。(见下文)
Spline
'Spline' 插值方法与上面的 '[Catrom](#catrom)' 一样,也使用最近的 16 个像素。不过这是一种非常模糊、类似高斯的插值方式。 |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate spline \
-fx 'v.p{i/(w-1),j/(h-1)}' interpolate_spline.jpg
![[IM 输出]](../static/img/misc/interpolate_spline.jpg)
可以看到,上面 'Spline' 插值结果中最角落的颜色被削弱了,因为插值生成的曲面实际上并没有经过那些像素的原始颜色。本质上,它是过度"模糊"的,更准确地说应称为 'B-Spline'(B样条)曲面。由于它是使用分段三次曲线技术生成的,这个曲面仍然属于一种 三次滤镜(b=1, c=0)。不过这条曲线只是趋近于原始像素颜色,尤其是在颜色剧烈变化的区域。也就是说,对某个精确整数像素位置进行插值查找时,得到的并不是该像素的实际颜色,而是与周围像素混合后的模糊颜色。这通常被认为是缺点,但也可以用作一种通用的平滑函数。和 '[Catrom](#catrom)' 一样,它也会受到周围像素的影响。
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Spline -virtual-pixel edge \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' interpolate_spline_edge.jpg
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Spline -virtual-pixel White \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' interpolate_spline_white.jpg
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate Spline -virtual-pixel Black \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' interpolate_spline_black.jpg
| 在真实图像中,虚拟像素的影响只出现在图像的边缘。因为在真实像素的情况下,查找所依据的像素间区域周围都有真实像素环绕。
---|---
在这里你可以看到,由于对像素颜色进行了拟合效果不佳的"spline"曲线插值,所产生的颜色柔化效果。其结果通常是彩色区域边缘变得更模糊,细线也是如此。不过它们也不会出现像"[Catrom](#catrom)"插值那样的负面"振铃"效应。
插值背景
由于插值的效果通常作用于较大的区域,这里放大展示了四种主要插值方法在白色或黑色环绕像素下的表现。
for method in bilinear mesh catrom spline ; do
for vpixel in white black ; do
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -interpolate $method -virtual-pixel $vpixel \
-fx 'v.p{3*i/(w-1)-1, 3*j/(h-1)-1}' ip_area_${method}_$vpixel.jpg
done
done
如你所见,对于"[bilinear](#bilinear)"插值出的颜色而言,周围的背景色实际上没有产生什么影响,看起来它只是简单地叠加在现有的任何背景色之上。不过你可以看到"[mesh](#mesh)"是如何生成更强烈、更锐利的边缘的,但当涉及图像边缘时,它可能会根据周围颜色的不同而决定翻转对角线方向。可以观察红色与蓝色之间、白色与黑色背景之间的交界处来看到这种"翻转"。而"[catrom](#catrom)"与"[spline](#spline)"的插值曲线则会受到周围像素的影响,尤其是在涉及绝对颜色的测试案例中更为明显。最后,"[spline](#spline)"插值实际上就是对图像进行类似高斯模糊的处理(使用 0.65 的 sigma 值)。这种程度的模糊足以消除任何"振铃"或锯齿效应,不过对大多数用途来说通常会显得过于模糊。参见高斯滤镜。
旋转直线的插值
这里我通过创建一条竖直线的图像,并使用仿射变形将该直线旋转 17 度,然后放大视图以便你能看到所生成的抗锯齿像素,来演示各种插值方法。
magick -size 10x20 xc: -draw 'line 4,0 4,20' \
-scale 50x100 ip_line_none.gif
for method in integer nearest bilinear mesh catrom spline; do
magick -size 10x20 xc: -draw 'line 5,0 5,20' \
-interpolate $method -filter point -distort SRT 17 \
-scale 50x100 ip_line_${method}.gif
done
![[IM 输出]](../static/img/misc/ip_line_none.gif)
未旋转 | | ![[IM 输出]](../static/img/misc/ip_line_integer.gif)
Integer | ![[IM 输出]](../static/img/misc/ip_line_nearestneighbor.gif)
Nearest | ![[IM 输出]](../static/img/misc/ip_line_bilinear.gif)
Bilinear | ![[IM 输出]](../static/img/misc/ip_line_mesh.gif)
Mesh | ![[IM 输出]](../static/img/misc/ip_line_catrom.gif)
Catrom | ![[IM 输出]](../static/img/misc/ip_line_spline.gif)
Spline
---|---|---|---|---|---|---|---
如你所见,直接颜色查找方法"Interger"和"NearestNeighbor"产生了明显的锯齿结果,但只使用了图像中原本存在的颜色。这两者之间的主要区别在于"Interger"往往会使结果图像向下、向左偏移半个像素。"Bilinear"、"Mesh"和"Catrom"通常会产生非常好且相似的结果(后面会详细说明),其中后者产生的旋转直线非常锐利。这几种方法通常都被认为是不错的解决方案。"Spline"插值方法会使细线产生明显的模糊,以此去除锯齿效应。不过"Spline"往往会使结果过度模糊,实际上更适合用于平滑渐变,而不是旋转直线。 |
上面示例中使用的特殊设置"[-filter](#filter) point"是为了确保Distort 运算符在确定最终像素颜色时只使用单点插值。如果不加这个设置,则会使用区域重采样,而不是插值查找,不过那样也会产生非常好的结果。 |
|---|---|
_请注意,在这些示例中我没有使用"[-rotate](https://imagemagick.org/command-line-options/#rotate)"运算符,因为该运算符使用的是像素错切(Shearing)方法来旋转图像,因此不会用到像素插值。 |
请参见旋转细线,其中展示了以这种方式使用 [-rotate](https://imagemagick.org/command-line-options/#rotate)" 运算符及其产生的像素级效果。
更新:从 IMv6.7.3-4 开始,rotate 运算符内部已改为使用Distort 运算符,因此上述说法可能已不再成立。
旋转边缘的插值
当被变形的是某一区域的边缘,而非单条像素线时,其结果会有细微差别。
magick -size 10x20 xc: -draw 'rectangle 0,0 4,19' \
-scale 50x100 ip_edge_none.gif
for method in integer nearest bilinear mesh catrom spline; do
magick -size 10x20 xc: -draw 'rectangle 0,0 4,19' \
-interpolate $method -filter point -distort SRT -17 \
-scale 50x100 ip_edge_${method}.gif
done
![[IM 输出]](../static/img/misc/ip_edge_none.gif)
未旋转 | | ![[IM 输出]](../static/img/misc/ip_edge_integer.gif)
Integer | ![[IM 输出]](../static/img/misc/ip_edge_nearestneighbor.gif)
Nearest | ![[IM 输出]](../static/img/misc/ip_edge_bilinear.gif)
Bilinear | ![[IM 输出]](../static/img/misc/ip_edge_mesh.gif)
Mesh | ![[IM 输出]](../static/img/misc/ip_edge_catrom.gif)
Catrom | ![[IM 输出]](../static/img/misc/ip_edge_spline.gif)
Spline
---|---|---|---|---|---|---|---
上面的结果基本上一目了然。"Bilinear"和"Mesh"在一般旋转情况下会产生相当锐利的边缘,而"Catrom"在变形后的图像中会产生更锐利的边缘。而"Spline"则会产生更模糊的边缘。在上述情况中,"Bilinear"和"Mesh"之间的差异极其微小。这两种方法只有在变形操作中出现极端放大的情况下才会真正产生可见的差异,否则你只能看到像素强度上轻微、几乎难以察觉的变化。
虚拟像素——缺失图像颜色的查找
许多运算符经常需要查找落在图像边界之外的颜色。这包括模糊图像、通用图像畸变、形态学与卷积运算符、通用畸变运算符,甚至是非常古老的内爆运算符等运算符。那么,如果你请求获取位于 -22,-3 处的像素,应该返回什么颜色呢?这样的像素实际上并不存在,但所返回的颜色值会对整个图像处理的效果产生深远影响,尤其是会影响到靠近图像实际边缘的像素的最终颜色。"[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)"设置定义了当访问图像正常边界之外的像素时,IM 应当返回什么值。
举例来说,这里我们使用 FX DIY 运算符"[-fx](https://imagemagick.org/command-line-options/#fx)"来"查找"并显示这张小图像内部及其周围的所有像素,这样我们就能看到默认的"[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)"设置所返回的结果。 |
magick -size 70x70 xc: tree.gif \
-fx 'v.p[-19,-19]' virtual_default.gif
![[IM 输出]](../static/img/misc/virtual_default.gif)
'Edge ' "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置会返回请求的“虚拟”位置最近的真实像素的颜色。也就是说,是最近似的“边缘”颜色。这次我会使用速度更快的使用视口进行图像畸变来展示周围的虚拟像素,而不是慢得多的FX 运算符。畸变方法 "SRT 0" 实际上并不会畸变图像结果,它只是查看图像运算符实际看到的像素,尤其是源图像周围的那些“虚拟”像素。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Edge -filter point -distort SRT 0 \
+repage virtual_edge.gif
![[IM 输出]](../static/img/misc/virtual_edge.gif)
'Edge' 虚拟像素设置是默认设置,所以上面的结果应该与前一个示例相同。在处理图像时,这个设置通常带来的(边缘效果方面的)影响最小,这也是它被选为默认设置的原因。当使用模糊或其他使用像素“邻域”进行处理的形态学与卷积运算符时,这一点尤为重要。需要注意的是,角像素的颜色最终会完全填满实际图像周围对角相邻的区域。这会导致单个角像素对各种图像变换产生很大影响。这种“角落”效应在模糊图像时尤为明显。 'Tile ' VP 设置对于生成并确保图像处理的边缘效果环绕图像边界非常有用。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Tile -filter point -distort SRT 0 \
+repage virtual_tile.gif
![[IM 输出]](../static/img/misc/virtual_tile.gif)
这可以确保正在处理的图像保持“可平铺”,或者在图像被修改的过程中变得更“可平铺”。更多示例请参见修改平铺图像。 'Mirror ' 与 '[tile](#tile)' 非常相似,对于某些效果可能比默认的 '[edge](#edge)' 更好。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Mirror -filter point -distort SRT 0 \
+repage virtual_mirror.gif
![[IM 输出]](../static/img/misc/virtual_mirror.gif)
这对于减少正在被模糊处理的图像的边缘和角落效应特别有用。不过它也会产生其他效果。 | _在 IM v6.5.0-1 之前,只有直接附着于原始图像的图像会被镜像。距离原图更远的其他虚拟副本仍保持未镜像状态(普通平铺模式)。这个问题已被修正,现在整个虚拟画布空间都能正确地进行镜像平铺,而不仅仅是相邻的虚拟副本。
只有在将镜像平铺与通用畸变运算符配合使用、对非常大的区域进行镜像平铺时,这一点才会变得重要,例如在观看远方地平线时_
---|---
'Transparent ' 只是为落在真实图像边界之外的像素返回透明色。 |
magick tree.gif -alpha set -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Transparent -filter point -distort SRT 0 \
+repage virtual_trans.gif
![[IM 输出]](../static/img/misc/virtual_trans.gif)
上面用到的Alpha 'set' 运算符是必需的,用以确保图像具有蒙版或 alpha 通道,从而让透明色能够正确填充。如果没有这个设置,上面的命令可能会返回“黑色”而不是透明色,因为颜色 'none'(即“完全透明的黑色”)是默认的透明色。举例来说,这里我不小心关闭了透明度…… |
magick tree.gif -alpha off -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Transparent -filter point -distort SRT 0 \
+repage virtual_trans2.gif
![[IM 输出]](../static/img/misc/virtual_trans2.gif)
'Transparent' 设置对图像畸变特别有用,因为畸变后的图像之后会被“分层叠加”以构建更大的图像。例如3D 仿射立方体和3D 透视方框。 'white '、'gray ' 和 'black ' 设置与前面的 'Transparent' 设置类似。它们只是为任何超出边界的像素返回相应的特定颜色。 |
magick tree.gif -alpha off -set option:distort:viewport 70x70-19-19 \
-virtual-pixel White -filter point -distort SRT 0 \
+repage virtual_white.gif
magick tree.gif -alpha off -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Gray -filter point -distort SRT 0 \
+repage virtual_gray.gif
magick tree.gif -alpha off -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Black -filter point -distort SRT 0 \
+repage virtual_black.gif
![[IM 输出]](../static/img/misc/virtual_black.gif)
如果你想使用其他任意的简单颜色,那么必须在 "[-background](https://imagemagick.org/command-line-options/#background)" 设置中定义该颜色,并使用 'Background ' "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Background -background coral \
-filter point -distort SRT 0 +repage virtual_bgnd.gif
'HorizontalTile ' VP 设置是在 IM v6.4.2-6 中新增的一种特殊平铺形式,适用于完整 360 度的 "[Arc](distorts.html#arc)" 和 "[Polar](distorts.html#polar)" 扭曲。图像只在水平方向上平铺,而平铺图块上方和下方的虚拟像素则由当前的 "[-background](https://imagemagick.org/command-line-options/#background)" 颜色设置。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel HorizontalTile -background coral \
-filter point -distort SRT 0 +repage virtual_horizontal.gif
![[IM 输出]](../static/img/misc/virtual_horizontal.gif)
这可以确保正在变换的图像在水平方向上保持“可平铺”。更多示例请参见修改平铺图像。 'HorizontalTileEdge '(在 IM v6.5.0-1 中新增)同样会在虚拟空间中沿水平方向平铺图像,但会将侧边缘像素复制到虚拟画布空间的其他部分。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel HorizontalTileEdge -background coral \
-filter point -distort SRT 0 +repage virtual_horizontal_edge.gif
![[IM 输出]](../static/img/misc/virtual_horizontal_edge.gif)
新增这两种 VP 方法是为了更好地处理完整圆形的 '[Arc](../static/img/distorts#arc)' 和 '[Polar](../static/img/distorts#polar)' 扭曲,此时被环绕的图像会“首尾相连”地环绕拼接起来。
类似地,'VerticalTile ' VP 设置(同样是在 IM v6.4.2-6 中为求完整性而新增的)只在垂直方向上平铺图像,图像两侧则用当前的 "[-background](https://imagemagick.org/command-line-options/#background)" 颜色填充。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel VerticalTile -background coral \
-filter point -distort SRT 0 +repage virtual_vertical.gif
![[IM 输出]](../static/img/misc/virtual_vertical.gif)
'VerticalTileEdge ' 是在 IM v6.5.0-1 中新增的,它会将侧边缘像素复制到虚拟画布空间的其余部分。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel VerticalTileEdge -background coral \
-filter point -distort SRT 0 +repage virtual_vertical_edge.gif
![[IM 输出]](../static/img/misc/virtual_vertical_edge.gif)
在 IM v6.5.0-1 中新增了 'CheckerTile ',它会以棋盘格图案的方式平铺图像。其余方格则简单地填充为背景色(可以是透明的)。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel CheckerTile -background coral \
-filter point -distort SRT 0 +repage virtual_checker.gif
![[IM 输出]](../static/img/misc/virtual_checker.gif)
通过将背景设为透明,并将该图像叠加到另一张同尺寸的完全平铺图像上,你可以将两种平铺图层叠加起来,从而生成两幅图像交错的棋盘格图案。 |
magick -size 96x96 tile:balloon.gif \
\( tree.gif -alpha set -set option:distort:viewport 96x96 \
-virtual-pixel CheckerTile -background none \
-filter point -distort SRT 0 \) \
-flatten virtual_checker_2.gif
还有几个比较特殊的 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置。 'random ' 只是从图像中随机挑选一个像素来使用。 |
magick tree.gif -set option:distort:viewport 70x70-19-19 \
-virtual-pixel Random -filter point -distort SRT 0 \
+repage virtual_random.gif
![[IM 输出]](../static/img/misc/virtual_random.gif)
这常与 "[-blur](https://imagemagick.org/command-line-options/#blur)" 搭配使用,用来在产生的边缘效果中生成粗糙斑驳的平均图像颜色。请注意,像素值并不固定,除非给随机数生成器指定一个初始的 "[-seed](https://imagemagick.org/command-line-options/#seed)",否则每次查找、甚至每次运行该操作都会产生不同的效果。这一点在配合卷积或形态学图像处理使用时尤其糟糕,因为图像边缘的每次查找即便使用相同的像素查找方式,也会得到不同的值。不过我发现在生成透视地平线时,随机图案的效果相当好,因为随着越来越接近地平线,图案会显示出更模糊的结果。这种模糊为最终得到的随机纹理带来了一种深度感,如果使用简单的纯色则不会有这种效果。
而 'dither ' 则会基于所请求位置附近 32x32 像素范围内的像素,返回一种有序抖动的颜色图案。这意味着一旦超出图像 32 像素的范围,结果就会再次变回图像角落像素的颜色。它有点像 '[edge](#edge)' 和 '[random](#random)' 的结合体。 |
magick tree.gif -set option:distort:viewport 120x120-44-44 \
-virtual-pixel Dither -filter point -distort SRT 0 \
+repage virtual_dither.gif
![[IM 输出]](../static/img/misc/virtual_dither.gif)
从上图可以看出,这张 32x32 像素图像一角的太阳黄色,一路被选取到了最远的右下角,但仅此而已。这就是有序抖动颜色选取所受的 32 像素“邻域”限制。如果图像更大,黄色的太阳就不会延伸到其他角落。这种图案并非“随机”,对同一图像总会生成相同的结果。可以把它看作是一种更有序的 '[random](#random)' VP,在靠近图像时表现如此,而一旦处理位置超出图像本身 32 像素之外,其效果就更接近于 '[edge](#edge)'。
虚拟像素与无穷远
你可以更清楚地看到 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 在通用畸变运算符结果中的效果,尤其是配合透视畸变时,它能让你创建出一直延伸到无穷远处的畸变视图。例如,这里展示了在树的透视视图上使用 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) dither" 设置的结果。这说明了该设置是如何一直影响到无穷远处所返回的像素的。
magick tree.gif -mattecolor DodgerBlue -virtual-pixel dither \
-set option:distort:viewport 150x100-50-50 \
-distort perspective '0,0 9,0 31,0 38,0 0,31 0,18 31,31, 40,18' \
perspective_dither.gif
请尝试在上例中使用其他 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置,以更好地理解它们的工作方式。其他一些示例也可以参见远眺地平线。请注意,上图中的“天空”实际上是由 "[-mattecolor](https://imagemagick.org/command-line-options/#mattecolor)" 设置生成的,该设置被 distort 用于表示“无效”区域,在此例中即透视扭曲的“天空”部分。它并非来自 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置。
虚拟像素颜色
"[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 的所有方法实际上都不会返回与图像中已有颜色不同的合成颜色,除非该颜色是通过某种纯色方法明确请求的,比如:'[background](#background)'、'[transparent](#transparent)'、'[background](#background)'、'[black](#black)'、'[white](#white)'、'[gray](#gray)';也就是说,从不会生成新的颜色,尽管可能会添加一种特定颜色(对于通用畸变运算符则是两种)。当然,如果所请求的像素正在进行像素插值或区域重采样,比如上面的透视畸变视图,那么这些方法可能会根据所选的 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置来合并返回的颜色。
虚拟像素对运算符的影响
这里我探讨一下 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置对各种运算符所产生的影响。"[-blur](https://imagemagick.org/command-line-options/#blur)"…… |
magick -size 70x70 xc:lightblue -fill black -draw 'circle 35,65 25,55' \
-virtual-pixel edge -blur 0x8 vp_blur.png
magick -size 70x70 xc:lightblue -fill black -draw 'circle 35,65 25,55' \
-virtual-pixel mirror -blur 0x8 vp_blur_2.png
![[IM 输出]](../static/img/misc/vp_blur_2.png)
请注意下例中,使用 "[-blur](https://imagemagick.org/command-line-options/#blur)" 并配合 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 的 'tile' 设置时,图像会如何相互沾染。当然,如果图像本身就是可平铺的,这种效果可能正是所需要的。 |
magick -size 70x70 xc:lightblue -fill black -draw 'circle 35,65 25,55' \
-virtual-pixel tile -blur 0x8 vp_blur_3.png
![[IM 输出]](../static/img/misc/vp_blur_3.png)
为图像的 "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置一个特定颜色,会产生一些非常有趣的效果和可能性。 |
magick -size 70x70 xc:lightblue -fill black -draw 'circle 35,65 25,55' \
-virtual-pixel background -background blue \
-blur 0x8 vp_blur_4.png
magick -size 70x70 xc:lightblue -fill black -draw 'circle 35,65 25,55' \
-virtual-pixel transparent -channel RGBA -blur 0x8 \
-background red -flatten vp_blur_5.png
![[IM 输出]](../static/img/misc/vp_blur_5.png)
注意我放在图像后面的'red'背景是如何在边缘周围显现出来的,这是因为生成的模糊图像使用了围绕图像真实像素的虚拟像素。"[-gaussian](https://imagemagick.org/command-line-options/#gaussian)"的基本效果与"[-blur](https://imagemagick.org/command-line-options/#blur)"相同,这是可以理解的,因为它们在数学上是完全相同的。 |
magick -size 70x70 xc:lightblue -fill black -draw 'circle 35,65 25,55' \
-virtual-pixel background -background blue \
-gaussian 0x8 vp_gaussian.png
![[IM 输出]](../static/img/misc/vp_gaussian.png)
然而"[-radial-blur](https://imagemagick.org/command-line-options/#radial-blur)"(实际上是一种旋转模糊)会产生更有趣的边界效果…… |
magick -size 70x70 xc:lightblue \
-virtual-pixel background -background blue \
-radial-blur 0x30 vp_radial.png
![[IM 输出]](../static/img/misc/vp_radial.png)
最后这个使用默认的'transparent edge'(透明边缘),在配合较大的径向模糊角度使用时,很可能会生成平滑的边缘。与其他技巧相比,它可能产生更干净的'晕影'或柔和边缘叠加图像。参见柔和与模糊的边缘以获取使用此效果的示例。请注意,"[-motion-blur](https://imagemagick.org/command-line-options/#motion-blur)"可能会受到边缘效果的严重影响。 | 更糟糕的是,"[-motion-blur](https://imagemagick.org/command-line-options/#motion-blur)"目前不支持使用"[-channel](https://imagemagick.org/command-line-options/#channel)"将其效果限制到特定通道。
---|---
|
magick -size 70x70 xc:none -virtual-pixel edge \
-fill yellow -stroke red -strokewidth 3 -draw 'circle 45,55 35,45' \
-channel RGBA -motion-blur 0x12+65 vp_motion.png
magick -size 70x70 xc:none -virtual-pixel transparent \
-fill yellow -stroke red -strokewidth 3 -draw 'circle 45,55 35,45' \
-channel RGBA -motion-blur 0x12+65 vp_motion_2.png
magick -size 70x70 xc:none -virtual-pixel background -background blue \
-fill yellow -stroke red -strokewidth 3 -draw 'circle 45,55 35,45' \
-channel RGBA -motion-blur 0x12+65 vp_motion_3.png
虚拟像素的内爆效果
下面是使用各种"-virtual-pixel"设置、采用各种较大数值(>1.0)的内爆效果的一些更有趣的示例。
for v in edge tile mirror dither random gray; do
for i in 2 5 10 50 500; do \
magick koala.gif -virtual-pixel $v \
-implode $i implode_${v}_${i}.gif
done
done
内爆 | 边缘 | 平铺 | 镜像 | 抖动 | 随机 | 灰色
---|---|---|---|---|---
2 |
|
|
|
|
| ![[IM 输出]](../static/img/misc/implode_gray_2.gif)
5 |
|
|
|
|
| ![[IM 输出]](../static/img/misc/implode_gray_5.gif)
10 |
|
|
|
|
| ![[IM 输出]](../static/img/misc/implode_gray_10.gif)
50 |
|
|
|
|
| ![[IM 输出]](../static/img/misc/implode_gray_50.gif)
500 |
|
|
|
|
|
上述结果所呈现出的“斑点状”特性,是 "-implode" 运算符所使用的直接“插值采样”的结果。参见直接插值查找。这在未来版本的 IM 中可能会改变,改用区域重采样。目前你需要使用超采样技术来改善结果。'edge'设置是更常用、也是默认使用的设置,可以避免大多数怪异效果。其他设置(除'background'外)本质上都是从图像中已有的像素生成重复图案,效果差异很大。另请注意,参数需要以指数级增长才能获得相似程度的效果增量。同样,当参数大于约 200 时,结果图像中央可能会出现一个黑色圆圈,这是计算机的数学极限所致。我们不建议使用如此大的数值。
纯色的随机斑点
通过对"plasma:fractal"画布进行模糊处理,再将颜色数量减少到非常低的值,就可以生成包含不同颜色随机区域的简单图像。然而结果会因最终请求的颜色数量以及虚拟像素设置(见上文)不同而有很大差异。在这个实验中,我最初的随机图像有两种选择:分形等离子图像和随机噪声图像。随机图像本身配合 'tile' "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" 设置时,能生成更适合平铺的图像。而等离子图像则倾向于在其色斑边缘形成类似矩形的形状。另一方面,等离子图像会产生相当漂亮的柔和色斑或色块,而随机图像则往往会产生难看的中间灰色调。正因如此,我选择在这些实验中使用等离子图像。
magick -size 80x80 plasma:fractal -normalize spot_start.gif
#magick -size 80x80 xc: +noise Random \
# -virtual-pixel tile -blur 0x5 -normalize spot_start.gif
for n in 2 3 4 5; do
for v in edge mirror tile white black; do
magick spot_start.gif -virtual-pixel $v -blur 0x10 \
+dither -colors $n spot${n}_${v}.gif
done
done
前三张图对彩色“斑点”与图像边缘的相互作用有非常具体的影响。'Edge' 和 'Mirror' 往往会让颜色以 90 度角接到边缘上。'Random' 或 'Dither' 设置也会让色块附着到图像边缘,而且效果类似但更强,不过二者也会在靠近图像边缘处引入一些锐利的边缘效果。可能需要再执行一轮 blur-quantize 循环,才能清理并平滑这些斑点的边缘。'Tile' 设置往往会让斑点绕图像边界环绕。不过,由于源 Plasma 图像本身不可平铺,结果会在矩形边缘附近出现整体性的颜色变化。如果使用可平铺的 Random 图像作为源图像,那么彩色斑点会完全无视图像边界。使用 'White' 或 'Black' 背景虚拟像素设置时,彩色斑点往往会集中在图像本体中央。这种“居中”效果有多好,取决于原始随机图像与所用“背景色”之间差异有多大。"[-blur](https://imagemagick.org/command-line-options/#blur)" 的尺寸基本上会影响色块的大小和平滑程度。较小的模糊会生成许多小斑点;较大的模糊(如上例所用)则会生成一个更接近圆形的单一色斑。
使用不同的颜色量化色彩空间,还可以产生一套完全不同的颜色与交互效果。例如,这里我们重复上面最后一个示例(将颜色减少到 5 种),但在颜色选择时使用一些更不寻常的"[-quantize](https://imagemagick.org/command-line-options/#quantize)"色彩空间。(参见颜色量化与色彩空间)
请记住,以上所有图像都是由同一张随机化的源图像生成的。你所看到的不同效果,是以不同方式减少图像颜色数量所产生的结果。你可以看到"[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)"设置——它定义了模糊在图像边界之外看到的像素颜色——对色块形状有着强烈的影响。
Annotate 参数用法
IM 版本 6 为文本绘制提供了一个新的命令行选项"[-annotate](https://imagemagick.org/command-line-options/#annotate)",它绕过了旧的"[-draw](https://imagemagick.org/command-line-options/#draw)"方式,直接使用 Annotate() API。这为命令行用户提供了一些新特性。在这个示例中,我选择了 Arial Black 字体,因为其字形笔直,可以让旋转效果一目了然。 |
magick -font ArialB -pointsize 24 -gravity center \
-size 55x55 xc:white -annotate 0x0+0+0 'Text' \
annotate_source.jpg
**-annotate {_SlewX_}x{_SlewY_}+{_X_}+{_Y_} 'Text String' **
上面的 X 和 Y 偏移量是要绘制的注释文本经过 gravity 影响后的位置。而 SlewX 和 SlewY 则代表一种旋转形式。如果这两个值相同,则执行的是普通旋转。但如果它们不同,就会产生一些非常有趣的效果……
可以看到,有些参数完全没有绘制出文本,基本上都是发生在文本本应被绘制成单独一行的情况下。这是预料之中的。不过你可以看到,我们能够以翻转、镜像、旋转、斜体等各种方式绘制文本。这是一个非常有用的图像运算符。
Splice:创建一个新的图像运算符
就在 ImageMagick 版本 6 首次发布后不久,围绕一个问题展开了一场讨论。这个问题涉及在图像中间插入额外的空间(行和列)。下面的例子是这场讨论所催生出的一套复杂命令,运用了 IM 版本 6 的强大魔法,详细说明了具体应该怎么做。正是从这个例子出发,才创建了"[-splice](https://imagemagick.org/command-line-options/#splice)"运算符(详情参见将行和列拼接与切割到图像中中的示例)。因此,这条命令行正是这个新命令的定义性操作,两者的工作方式应当完全一致。 |
magick rose: -size 20x10 xc:blue -background blue \
\( -clone 0 -crop 40x0 +repage +clone -insert 1 +append \) \
-swap 0,-1 +delete +repage \
\( -clone 0 -crop 0x30 +repage +clone -insert 1 -append \) \
-delete 0 -delete 0 +repage splice_rose_seq.gif
![[IM 输出]](../static/img/misc/splice_rose_seq.gif)
在上面的例子中,我们把玫瑰图像切成许多竖条,然后在这个序列中插入一张间隔用的图像,再将它们全部重新拼接在一起。基本上,我们是在玫瑰图像中加入了一列竖直的像素。然后,用修改后的图像替换掉原始图像,我们又重复了同样的操作,只不过这次是水平方向。再对中间使用的图像稍作清理,就大功告成了。这个例子还向邮件列表展示了 IM 版本 6 新的有序命令行处理方式以及图像序列运算符的实用性。在旧版本的 IM 中,要达成同样的效果,需要大量单独的命令和临时图像。
Border、Frame 以及 BorderColor 的使用
存在这样一种争论:认为"[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)"应该只用于配合"[-border](https://imagemagick.org/command-line-options/#border)"或"[-frame](https://imagemagick.org/command-line-options/#splice)"给图像添加边框。也就是说,许多用户认为它不应该被用来设置带透明度图像背后的背景。例如,在 IM 中,下面这条命令会将星形图像的透明区域设置为"[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)",而完全忽略"[-background](https://imagemagick.org/command-line-options/#background)"颜色设置。 |
magick star.gif -bordercolor LimeGreen -background Gold \
-border 10 star_border.gif
![[IM 输出]](../static/img/misc/star_border.gif)
之所以用"[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)"来设置透明图像的背景,主要原因是这样可以让"magick montage"在处理一组可能包含透明度、且用户只做了最少设置的随机图像时,呈现出美观的效果。 |
magick montage star.gif -frame 6 -geometry '64x64+5+5>' star_montage.gif
![[IM 输出]](../static/img/misc/star_montage.gif)
如果保留了透明度,上面"magick montage"的结果就不会显得那么美观。但这并不意味着在使用"[-border](https://imagemagick.org/command-line-options/#border)"或"[-frame](https://imagemagick.org/command-line-options/#splice)"运算符时就无法保留图像的透明度。这只是意味着你需要额外提供一个"[-compose](https://imagemagick.org/command-line-options/#compose)"设置,来告诉 IM 保留透明度。 |
magick star.gif -bordercolor LimeGreen \
-compose Copy -border 10 star_border_copy.gif
magick montage star.gif -bordercolor LimeGreen \
-compose Copy -background None -frame 6 \
-geometry '64x64+0+0>' star_montage_copy.gif
![[IM 输出]](../static/img/misc/star_border_copy.gif)
![[IM 输出]](../static/img/misc/star_montage_copy.gif)
关于在添加"[-border](https://imagemagick.org/command-line-options/#border)"或"[-frame](https://imagemagick.org/command-line-options/#splice)"的同时保留图像透明背景的更多信息,参见添加边框;关于"magick montage",参见montage 背景与透明度处理示例。有人提出过一种替代方案,即将这些运算符中的图像区域背景设置为"[-background](https://imagemagick.org/command-line-options/#background)"颜色,但这会干扰它在"magick montage"中的使用。当然,你也完全可以在添加任何额外的边框或 border 之前,自己先去除图像的透明度。在这种情况下,使用"-compose Copy"就变得无关紧要了。 |
magick montage star.gif -background Gold -alpha remove \
-frame 6 -geometry '64x64+5+5>' -size 16x16 \
-bordercolor LimeGreen -background SeaGreen \
star_montage_texture.gif
![[IM 输出]](../static/img/misc/star_montage_texture.gif)
使用"[-compose](https://imagemagick.org/command-line-options/#compose)"设置来保留透明度,要比让边框来保留透明度、进而引发其他问题简单得多。对新用户来说这或许并不显而易见,但这正是这些示例页面存在的意义。
List 运算符测试
以下所有命令都应该生成完全相同的图像,但每张图像都是以略有不同的方式生成的,展示了 IM 版本 6 新增的图像列表运算符。 |
magick eye.gif news.gif storm.gif +append list_test_01.gif
magick \( \) eye.gif news.gif storm.gif +append list_test_02.gif
magick eye.gif news.gif storm.gif \( \) +append list_test_03.gif
magick \( eye.gif news.gif storm.gif \) +append list_test_04.gif
magick \( eye.gif news.gif storm.gif +append \) list_test_05.gif
magick eye.gif \( news.gif storm.gif +append \) +append list_test_06.gif
magick \( eye.gif news.gif +append \) storm.gif +append list_test_07.gif
magick \( storm.gif -flop \) \( news.gif -flop \) \( eye.gif -flop \) \
+append -flop list_test_08.gif
magick \( eye.gif -rotate 90 \) \( news.gif -rotate 90 \) \
\( storm.gif -rotate 90 \) -append -rotate -90 list_test_09.gif
magick eye.gif tree.gif news.gif storm.gif -delete 1 \
+append list_test_10.gif
magick eye.gif tree.gif news.gif storm.gif -delete -3 \
+append list_test_11.gif
magick eye.gif news.gif storm.gif tree.gif +delete \
+append list_test_12.gif
magick news.gif storm.gif eye.gif +insert +append list_test_13.gif
magick eye.gif storm.gif news.gif -insert 1 +append list_test_14.gif
magick news.gif eye.gif storm.gif -swap 0,1 +append list_test_15.gif
magick storm.gif news.gif eye.gif -swap 0 +append list_test_16.gif
magick eye.gif storm.gif news.gif +swap +append list_test_17.gif
magick eye.gif storm.gif news.gif \( -clone 1 \) \
-delete 1 +append list_test_18.gif
magick eye.gif -negate \( +clone -negate \) news.gif storm.gif \
-delete 0 +append list_test_19.gif
magick storm.gif news.gif eye.gif \( -clone 2,1,0 \) \
-delete 2,1,0 +append list_test_20.gif
magick storm.gif news.gif eye.gif \( -clone 2-0 \) \
-delete 0-2 +append list_test_21.gif
magick {balloon,medical,present,shading}.gif -delete 0--1 \
{eye,news,storm}.gif +append list_test_22.gif
magick balloon.gif -delete 0,0,0,0,0,0,0,0,0 \
eye.gif news.gif storm.gif +append list_test_23.gif
magick eye.gif balloon.gif news.gif storm.gif \
-delete 1,1,1,1,1 +append list_test_24.gif
magick {balloon,medical,present,shading}.gif {eye,news,storm}.gif \
-delete 0--4 +append list_test_25.gif
magick eye.gif news.gif storm.gif \
-delete 0--4 +append list_test_26.gif
magick storm.gif news.gif eye.gif -reverse +append list_test_27.gif
![[IM 输出]](../static/img/misc/ip_color_integer.jpg)
![[IM 输出]](../static/img/misc/ip_color_nearest.jpg)
![[IM 输出]](../static/img/misc/ip_color_blend.jpg)
![[IM 输出]](../static/img/misc/ip_color_average.jpg)
![[IM 输出]](../static/img/misc/ip_color_average9.jpg)
![[IM 输出]](../static/img/misc/ip_color_average16.jpg)
![[IM 输出]](../static/img/misc/interpolate_bilinear.jpg)
![[IM 输出]](../static/img/misc/interpolate_catrom_edge.jpg)
![[IM 输出]](../static/img/misc/interpolate_catrom_white.jpg)
![[IM 输出]](../static/img/misc/interpolate_catrom_black.jpg)
![[IM 输出]](../static/img/misc/interpolate_spline_edge.jpg)
![[IM 输出]](../static/img/misc/interpolate_spline_white.jpg)
![[IM 输出]](../static/img/misc/interpolate_spline_black.jpg)
![[IM 输出]](../static/img/misc/ip_area_bilinear_white.jpg)
![[IM 输出]](../static/img/misc/ip_area_mesh_white.jpg)
![[IM 输出]](../static/img/misc/ip_area_catrom_white.jpg)
![[IM 输出]](../static/img/misc/ip_area_spline_white.jpg)
![[IM 输出]](../static/img/misc/ip_area_bilinear_black.jpg)
![[IM 输出]](../static/img/misc/ip_area_mesh_black.jpg)
![[IM 输出]](../static/img/misc/ip_area_catrom_black.jpg)
![[IM 输出]](../static/img/misc/ip_area_spline_black.jpg)
![[IM 输出]](../static/img/misc/virtual_white.gif)
![[IM 输出]](../static/img/misc/virtual_gray.gif)
![[IM 输出]](../static/img/misc/virtual_bgnd.gif)
![[IM 输出]](../static/img/misc/virtual_checker_2.gif)
![[IM 输出]](../static/img/misc/perspective_dither.gif)
![[IM 输出]](../static/img/misc/vp_blur.png)
![[IM 输出]](../static/img/misc/vp_blur_4.png)
![[IM 输出]](../static/img/misc/vp_motion.png)
![[IM 输出]](../static/img/misc/vp_motion_2.png)
![[IM 输出]](../static/img/misc/vp_motion_3.png)
![[IM 输出]](../static/img/misc/spot2_edge.gif)
![[IM 输出]](../static/img/misc/spot2_mirror.gif)
![[IM 输出]](../static/img/misc/spot2_tile.gif)
![[IM 输出]](../static/img/misc/spot2_white.gif)
![[IM 输出]](../static/img/misc/spot2_black.gif)
![[IM 输出]](../static/img/misc/spot3_edge.gif)
![[IM 输出]](../static/img/misc/spot3_mirror.gif)
![[IM 输出]](../static/img/misc/spot3_tile.gif)
![[IM 输出]](../static/img/misc/spot3_white.gif)
![[IM 输出]](../static/img/misc/spot3_black.gif)
![[IM 输出]](../static/img/misc/spot4_edge.gif)
![[IM 输出]](../static/img/misc/spot4_mirror.gif)
![[IM 输出]](../static/img/misc/spot4_tile.gif)
![[IM 输出]](../static/img/misc/spot4_white.gif)
![[IM 输出]](../static/img/misc/spot4_black.gif)
![[IM 输出]](../static/img/misc/spot5_edge.gif)
![[IM 输出]](../static/img/misc/spot5_mirror.gif)
![[IM 输出]](../static/img/misc/spot5_tile.gif)
![[IM 输出]](../static/img/misc/spot5_white.gif)
![[IM 输出]](../static/img/misc/spot5_black.gif)
![[IM 输出]](../static/img/misc/spot_RGB_edge.gif)
![[IM 输出]](../static/img/misc/spot_RGB_mirror.gif)
![[IM 输出]](../static/img/misc/spot_RGB_tile.gif)
![[IM 输出]](../static/img/misc/spot_RGB_white.gif)
![[IM 输出]](../static/img/misc/spot_RGB_black.gif)
![[IM 输出]](../static/img/misc/spot_YIQ_edge.gif)
![[IM 输出]](../static/img/misc/spot_YIQ_mirror.gif)
![[IM 输出]](../static/img/misc/spot_YIQ_tile.gif)
![[IM 输出]](../static/img/misc/spot_YIQ_white.gif)
![[IM 输出]](../static/img/misc/spot_YIQ_black.gif)
![[IM 输出]](../static/img/misc/spot_HSL_edge.gif)
![[IM 输出]](../static/img/misc/spot_HSL_mirror.gif)
![[IM 输出]](../static/img/misc/spot_HSL_tile.gif)
![[IM 输出]](../static/img/misc/spot_HSL_white.gif)
![[IM 输出]](../static/img/misc/spot_HSL_black.gif)
![[IM 输出]](../static/img/misc/spot_XYZ_edge.gif)
![[IM 输出]](../static/img/misc/spot_XYZ_mirror.gif)
![[IM 输出]](../static/img/misc/spot_XYZ_tile.gif)
![[IM 输出]](../static/img/misc/spot_XYZ_white.gif)
![[IM 输出]](../static/img/misc/spot_XYZ_black.gif)
![[IM 输出]](../static/img/misc/spot_OHTA_edge.gif)
![[IM 输出]](../static/img/misc/spot_OHTA_mirror.gif)
![[IM 输出]](../static/img/misc/spot_OHTA_tile.gif)
![[IM 输出]](../static/img/misc/spot_OHTA_white.gif)
![[IM 输出]](../static/img/misc/spot_OHTA_black.gif)
![[IM 输出]](../static/img/misc/annotate_source.jpg)
![[IM 输出]](../static/img/misc/annotate_montage.jpg)
![[IM 输出]](../static/img/misc/list_test_01.gif)
![[IM 输出]](../static/img/misc/list_test_02.gif)
![[IM 输出]](../static/img/misc/list_test_03.gif)
![[IM 输出]](../static/img/misc/list_test_04.gif)
![[IM 输出]](../static/img/misc/list_test_05.gif)
![[IM 输出]](../static/img/misc/list_test_06.gif)
![[IM 输出]](../static/img/misc/list_test_07.gif)
![[IM 输出]](../static/img/misc/list_test_08.gif)
![[IM 输出]](../static/img/misc/list_test_09.gif)
![[IM 输出]](../static/img/misc/list_test_10.gif)
![[IM 输出]](../static/img/misc/list_test_11.gif)
![[IM 输出]](../static/img/misc/list_test_12.gif)
![[IM 输出]](../static/img/misc/list_test_13.gif)
![[IM 输出]](../static/img/misc/list_test_14.gif)
![[IM 输出]](../static/img/misc/list_test_15.gif)
![[IM 输出]](../static/img/misc/list_test_16.gif)
![[IM 输出]](../static/img/misc/list_test_17.gif)
![[IM 输出]](../static/img/misc/list_test_18.gif)
![[IM 输出]](../static/img/misc/list_test_19.gif)
![[IM 输出]](../static/img/misc/list_test_20.gif)
![[IM 输出]](../static/img/misc/list_test_21.gif)
![[IM 输出]](../static/img/misc/list_test_22.gif)
![[IM 输出]](../static/img/misc/list_test_23.gif)
![[IM 输出]](../static/img/misc/list_test_24.gif)
![[IM 输出]](../static/img/misc/list_test_25.gif)
![[IM 输出]](../static/img/misc/list_test_26.gif)
![[IM 输出]](../static/img/misc/list_test_27.gif)