ImageMagick 示例 --
其他杂项

索引
ImageMagick 示例前言和索引
插值 (像素间颜色查找)
虚拟像素 (缺失图像颜色查找)
随机的纯色斑点
Annotate 参数用法
拼接:创建新的图像操作符
边框、框架和 BorderColor 的使用
列表操作符测试
此页面包含一些测试 ImageMagick 各种方面的示例,但这些示例并不完全适合其他示例页面中的讨论(至少在形式上不是)。此页面还包含一些表格,演示了使用特定 IM 操作符的版本参数的结果。但是其他人也做过类似的事情,除非我有一些需要补充的内容,否则我不会进一步处理。

像素插值或像素间颜色查找

当在源图像中查找颜色时,使用“-interpolate”设置,但该“查找点”落在源图像的像素之间。这在各种图像操作中进行,例如“-fx”(DIY 特效操作符)和“-distort”(广义图像扭曲操作符),以及其他相关的操作符,如 圆形扭曲。基本上,“插值”告诉 IM 如何解释来自图像的直接颜色查找,当该点与图像中的实际像素不完全匹配,而是落在像素之间的空间时。例如,如果您查找像素位置 3,4 处的颜色,则应该获得精确的像素颜色。但是,如果您在点 3.23,4.75 处查找图像的颜色,IM 应该返回什么?您应该获取 3,43,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 Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
整数 最近邻 混合 平均 平均9 平均16
在 IM v6.7.7-6 之前,“Average”实际上等效于现在称为“Average16”的内容。其他两个平均插值器以及“Blend”和“Background”是在此时添加的。
还提供了一种其他简单的插值方法,“Background”,它只是为源图像的任何“采样”返回当前背景颜色。在许多方面,这相当无用,因为通常您最终只会得到一个空白的纯色图像。它的主要用途是作为更复杂的重采样函数的检查,例如重采样失败,其中 EWA 重采样滤镜(通常从广义扭曲操作符中使用)在重采样未能在其“支持”或重采样区域中找到任何像素时,将回退到插值查找。通过将插值设置为“Background”并将背景颜色设置为突出的颜色(如“red”),然后您可以查看结果图像中的像素,以查看重采样在何处“失败”或由于某种原因“错过了所有源图像像素”。通常是由于支持设置太小,或者玩弄了专家滤镜选项。未来:可能未来的插值选项是“随机”选择插值区域。可能对花哨的插值效果有用!

双线性

Bilinear”(或线性插值)是默认的插值方法,可能是从组合查找或采样点周围像素的颜色获得真实插值结果的最简单方法之一。这是一个解释双线性插值如何工作的图表。
[diagram]
也就是说,它只是在正交方向上连接直线以找到给定采样点的颜色。当与调整大小一起使用时,结果也等效于三角形重采样滤镜

  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
[IM Output]

  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 Output]
最后这张图片显示了如何在四个已知点之间的边缘形成线性渐变,然后在这些边缘之间形成第二个线性渐变。也就是说,周围像素之间的颜色是使用水平和垂直线性渐变生成的。这反过来又产生了一个通常称为“鞍形”的弯曲二维渐变,因为它在两个相对的角上升高,而在另外两个角上降低。您甚至可以使用此方法更直接地生成 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 Output]
这种默认插值方法最重要的方面是,图像的中心像素将始终是所有四个角颜色的平均值,边缘具有完美的线性渐变,并且角处具有精确的颜色匹配。

网格

-interpolate”设置为“Mesh”是“双线性”插值的变体。虽然“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 Output]
如您所见,“Mesh”算法产生的颜色插值集几乎与“双线性”完全相同。但是,如果我们反转黄色和青色…

  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 Output]
这次,“Mesh”算法确定“blue”和“cyan”颜色是最接近的两个角,并在这两个角之间创建了一个对角线线性渐变。然后其余的颜色从这条线到其他两个角形成一个简单的扁平三角形渐变。这可能看起来像是一种不寻常的插值,但该方法确保当彩色图像仅稍微调整大小、旋转或剪切时,锐利边界仍然保持相当锐利。事实上,自适应调整大小操作(“-adaptive-resize”)利用这一事实进行小的图像调整大小,以减少结果的过度模糊。例如,如果我们有一个“白色”角,“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 Output]
当然,如果颜色产生相当一致的渐变,则“网格”插值也会产生相当一致的渐变。

  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 Output]
如您所见,结果是相当合理的渐变,尽管如果您仔细观察,您可以看到两个独立三角形的对角线连接处。变化不如双线性(双线性也不是完全平滑的)平滑,但这些也不会尝试在调整大小或扭曲的图像中保留锐利的边缘。

Catrom(Catmull-Rom)

-interpolate” 设置为 'Catrom'(通常不精确地称为 'BiCubic' 插值),在确定点查找的颜色方面更加复杂。基本上,它不仅查看像素间区域角点处的颜色,而且进一步查看超出那些最近邻像素的颜色。在采样点周围的 4x4 区域中总共有 16 个像素。基本上,它将曲线拟合到所涉及的整个区域,以便确定要使用的最佳整体颜色。这是一个可能更好地解释该过程的图表……
[diagram]
这是我们标准四种颜色的插值颜色。

  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 Output]
上图可能看起来非常类似于 'Bilinear' 插值,但是结果具有更平滑的混合曲线,而不是直线来产生插值颜色。但是,此图像没有显示的是围绕我们四个近邻像素的其他像素的影响。为此,我们需要查看稍大的区域。对于此特定(非常小)示例,周围像素受 虚拟像素 设置控制。

  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
[IM Output] [IM Output] [IM Output]
在真实图像中,虚拟像素 的影响通常只影响图像边缘附近的区域。由于此图像只有 2 个像素宽,因此上述示例受到强烈影响。在更大更典型的图像中并非如此。
如您所见,曲线受到周围颜色的强烈影响,导致颜色变化非常紧密锐利,或者根据周围颜色定义的更混合的颜色变化。但是您还可以看到,周围像素颜色的强烈变化会导致该颜色的反向或负数的小区域。这是一个 环绕伪影,通常仅在真实图像中互补颜色的极其锐利的边缘上可见。
在非常强的颜色边缘上,这种环绕效应可能会被裁剪,从而导致一行可怕的像素。可以通过在不同于 'RGB' 的颜色空间(例如 'Lab' 或 'Luv' 颜色空间)中进行调整大小和插值来防止此问题。

有关此问题的更多信息和示例,请参阅 在 LAB 颜色空间中调整大小

请注意,'BiCubic'(插值 三次滤镜)是指一个非常庞大的滤镜系列,因此其含义非常不精确。但是它仍然可用,但其使用已弃用,取而代之的是更精确的名称。

在 IM v6.7.7-7 之后,'BiCubic' 只是 '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” 插值方法与上面的“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 Output]
如您所见,上述“Spline” 插值的角点处的颜色被抑制了,因为插值曲面实际上并没有穿过这些像素的原始颜色。从本质上讲,它过度“模糊”,更准确地称为“B 样条”曲面。该曲面仍然是一种 三次滤镜(b=1,c=0),因为它使用分段三次曲线的技术生成。但是,此曲线仅接近原始像素颜色,尤其是在颜色变化剧烈的区域。也就是说,对精确整数像素位置的插值查找不会返回该像素的实际颜色,而是该颜色与周围像素的模糊。这通常被认为是不好的,但可以用作通用平滑函数。与“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
[IM Output] [IM Output] [IM Output]
在真实图像中,虚拟像素 的影响仅在图像边缘。使用来自进行查找的像素间区域的真实像素。
在这里,您可以看到由于“样条”曲线与像素颜色拟合不良而导致的颜色抑制的影响。结果通常是彩色区域和细线的边缘更模糊。但是,它们也不会表现出使用“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
[IM Output] [IM Output] [IM Output] [IM Output]
[IM Output] [IM Output] [IM Output] [IM Output]
双线性 网格 Catrom 样条曲线
如您所见,周围背景颜色对“bilinear” 插值颜色没有真正的影响。看起来它只是覆盖在任何存在的背景颜色上。但是,您可以看到“mesh” 如何生成更强更锐利的边缘,但可以决定根据周围颜色翻转对角线,当它参与图像边缘时。查看红色和蓝色之间的连接处,白色和黑色背景之间的连接处以查看此“翻转”。“catrom” 和“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 Output]
未旋转
==> [IM Output]
整数
[IM Output]
最近邻
[IM Output]
双线性
[IM Output]
网格
[IM Output]
Catrom
[IM Output]
样条曲线
如您所见,直接颜色查找方法“Interger” 和“NearestNeighbor” 会产生高度混叠的结果,但仅使用图像中找到的原始颜色。两者之间的主要区别在于“Interger” 倾向于将生成的图像向下和向左移动半个像素。“Bilinear”、“Mesh” 和“Catrom” 通常会产生非常好的类似结果(稍后详细介绍),后者会产生一条非常锐利的旋转线。通常认为这些方法中的任何一种都是一个好的解决方案。“Spline” 插值方法会使细线产生明显的模糊,从而消除混叠效应。但是,“Spline” 倾向于过度模糊结果,并且实际上更适合平滑渐变,而不是旋转线。
特殊设置“-filter point” 在上述示例中用于确保 扭曲运算符 仅在确定最终像素颜色时使用单点插值。否则,将使用 区域重采样 而不是 插值查找,尽管这也会产生非常好的结果。
请注意,我没有在这些示例中使用“-rotate” 运算符,因为该运算符使用像素剪切方法来 旋转 图像。因此,不使用像素插值。

请参阅 旋转细线,了解以这种方式使用“-rotate” 运算符的示例以及产生的像素级效果。

更新:从 IMv7.7.3-4 开始,旋转运算符现在在内部使用 扭曲运算符,因此上述内容可能不再适用。

旋转边缘的插值

与单个像素行相比,当区域的边缘被扭曲时,结果会略有不同。

  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 Output]
未旋转
==> [IM Output]
整数
[IM Output]
最近邻
[IM Output]
双线性
[IM Output]
网格
[IM Output]
Catrom
[IM Output]
样条曲线
以上内容不言而喻。“Bilinear” 和“Mesh” 为一般旋转生成相当锐利的边缘,而“Catrom” 将在扭曲的图像中生成更锐利的边缘。“Spline” 然而将产生更模糊的边缘。“Bilinear” 和“Mesh” 之间的差异在上述情况下非常小。这两种方法仅在扭曲操作期间极度放大的情况下才会产生可见的差异。否则,您只会看到像素强度略微几乎无法察觉的变化。

虚拟像素错过的图像颜色查找

许多运算符通常需要查找超出图像本身边界的颜色。这包括 模糊图像一般图像扭曲形态和卷积运算符一般扭曲运算符 甚至非常旧的 内爆运算符 的运算符。因此,如果您请求 -22,-3 处的像素,应该返回什么颜色?这样的像素实际上并不存在,但是返回的颜色值会对图像处理的整体效果产生深远的影响,尤其是图像实际边缘附近的像素的最终颜色。“-virtual-pixel” 设置定义了当访问图像正常边界之外的像素时,IM 应该返回什么。 [IM Output] 例如,这里我们使用 FX DIY 运算符-fx” 来“查找”并显示小图像中和周围的所有像素,以便我们可以看到默认-virtual-pixel” 设置返回的内容。

  magick -size 70x70 xc:  tree.gif \
                  -fx 'v.p[-19,-19]'  virtual_default.gif
[IM Output]
'Edge' “-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 Output]
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 Output]
这使您可以确保正在处理的图像保持“可平铺”,或者在图像修改时变得更“可平铺”。有关更多示例,请参阅修改平铺图像Mirror” 与“tile” 非常相似,并且对于某些效果可能比默认的“edge” 更好。

  magick tree.gif  -set option:distort:viewport 70x70-19-19 \
          -virtual-pixel Mirror -filter point   -distort SRT 0 \
          +repage virtual_mirror.gif
[IM Output]
这在减少正在模糊的图像的边缘和角部效应方面特别有用。但是它也可以产生其他效果。
直到 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 Output]
上面的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 Output]
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
[IM Output]

  magick tree.gif  -alpha off  -set option:distort:viewport 70x70-19-19 \
          -virtual-pixel Gray -filter point  -distort SRT 0 \
          +repage virtual_gray.gif
[IM Output]

  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 Output]
如果您想要任何其他简单的颜色,则必须在“-background” 设置中定义该颜色,并使用“Background” “-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
[IM Output]

HorizontalTile” VP 设置作为一种特殊的平铺形式添加到 IM v6.4.2-6 中,它对于完整的 360 度“Arc” 和 “Polar” 扭曲很有用。图像仅水平平铺,而平铺上方和下方的虚拟像素则从当前的“-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 Output]
这使您可以确保正在转换的图像在水平方向上保持“可平铺”。有关更多示例,请参阅修改平铺图像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 Output]
添加这两种 VP 方法是为了更好地处理完整的圆形“Arc” 和 “Polar” 扭曲,其中环绕的图像“环绕”并首尾相连。
同样,“VerticalTile” VP 设置(也添加到 IM v6.4.2-6 中,为了完整性)仅垂直平铺图像,并使用当前的“-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 Output]
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 Output]
在 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 Output]
通过使背景透明并将该图像叠加在另一个相同大小的完全平铺的图像上,您可以将两个平铺层叠以产生两个图像的交错棋盘图案。

  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
[IM Output]

还有一些更不常见的“-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 Output]
这通常与“-blur” 一起使用,以在生成的边缘效果中生成粗糙的斑驳平均图像颜色。请注意,像素值不一致,并且每次查找甚至每次运行操作都会产生不同的效果,除非随机数生成器给出了初始“-seed”。当与卷积形态学图像处理一起使用时,这一点尤其糟糕,因为沿着图像边缘的每次查找都会贡献不同的值,即使使用了相同的像素查找。但是,我发现随机模式在生成透视地平线时非常好,因为该模式在您越靠近地平线时会显示出更模糊的结果。模糊使生成的随机纹理具有深度,否则如果使用简单的纯色则不会可见。
dither” 返回基于请求位置 32x32 像素内的像素的颜色有序抖动图案。
这意味着一旦您从图像移动到 32 个像素之外,结果将再次只是图像的角像素颜色。它有点像“edge” 和 “random” 的合并。

  magick tree.gif  -set option:distort:viewport 120x120-44-44 \
          -virtual-pixel Dither -filter point  -distort SRT 0 \
          +repage virtual_dither.gif
[IM Output]
在上面,您可以看到来自此 32x32 像素图像的一个角的太阳的黄色设法一直被选中到最右下角,但没有更远。也就是说,有序抖动颜色选择的 32 像素“邻域”的限制。如果此图像更大,黄色太阳颜色将无法到达其他角。此图案不是“随机的”,并且对于相同的图像始终会生成相同的结果。您可以将其视为“random” VP 在靠近图像时的一种更有序的形式,但在处理超出图像本身 32 个像素之外时,其效果更像是“edge” 的效果。

虚拟像素和无限

您可以更清楚地看到“-virtual-pixel” 的效果,尤其是在通用扭曲运算符的结果中,尤其是在透视扭曲中,允许您创建扭曲的视图到无限远处。例如,这里我展示了“-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
[IM Output]
尝试使用其他“-virtual-pixel” 设置以更好地了解它们的工作原理。在查看远方地平线中还可以看到其他一些示例。请注意,上面视图中的“天空”实际上是从“-mattecolor” 设置生成的,扭曲使用该设置来表示“无效”区域,在本例中为透视扭曲的“天空”。它不是来自“-virtual-pixel” 设置。

虚拟像素颜色

没有一种“-virtual-pixel” 方法实际上会返回与图像中已存在的颜色不同或复合的颜色,除非通过以下某种纯色方法专门请求该颜色:“background”、“transparent”、“background”、“black”、“white”、“gray”;也就是说,永远不会生成新的颜色,尽管可以添加一种特定颜色(通用扭曲运算符 有两种)。当然,如果请求的像素正在像素插值区域重采样,例如上图中的透视扭曲视图,则这些方法可能会根据所选的“-virtual-pixel” 设置合并返回的颜色。

虚拟像素对运算符的影响

在这里,我探讨了“-virtual-pixel” 设置对各种运算符的影响。“-blur”……

  magick -size 70x70 xc:lightblue  -fill black -draw 'circle 35,65 25,55' \
          -virtual-pixel edge   -blur 0x8     vp_blur.png
[IM Output]

    magick -size 70x70 xc:lightblue  -fill black -draw 'circle 35,65 25,55' \
            -virtual-pixel mirror  -blur 0x8  vp_blur_2.png
[IM Output]
请注意,在以下情况下,如何使用“-blur” 和“-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 Output]
为图像中的“-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
[IM Output]

  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 Output]
请注意,我放置在图像后面的“红色”背景如何在模糊图像已使用围绕图像真实像素的虚拟像素的边缘周围可见。“-gaussian” 的基本结果与“-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 Output]
但是“-radial-blur”(实际上是旋转模糊)会产生更有趣的边界效果……

  magick -size 70x70 xc:lightblue \
     -virtual-pixel background  -background blue \
     -radial-blur 0x30    vp_radial.png
[IM Output]
当与较大的径向模糊角度一起使用时,最后一个使用默认的“透明边缘”可能会生成平滑的边缘。它可能比其他技术产生更清晰的“晕影”或柔和的边缘叠加图像。有关使用此效果的示例,请参阅柔和和模糊的边缘。请注意,“-motion-blur” 可能会受到边缘效应的严重影响。
更糟糕的是,“-motion-blur” 目前不了解“-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
[IM Output]

  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
[IM Output]

  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
[IM Output]

虚拟像素的内爆效果

以下是一些使用各种“-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 Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
5 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
10 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
50 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
500 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
上述结果的“点状”性质是“-implode”操作符使用的直接“插值采样”的直接结果。参见直接插值查找。这可能会在 IM 的未来版本中发生变化,使用区域重采样。目前,您需要使用超级采样技术来改进结果。“edge”设置是更常用且默认的设置,用于避免大多数奇怪的效果。其他设置(除了“background”之外)本质上会从图像中现有的像素生成重复的图案,并且效果差异很大。还要注意,参数需要大小呈指数级增长才能获得类似的效果增长。此外,对于大于约 200 的参数,结果图像的中心可能会出现黑色圆圈。这是因为计算机的数学极限已达到。我们不建议您使用如此大的值。

随机的纯色斑点

通过模糊“plasma:fractal”画布,然后将颜色减少到非常低的值,您可以生成包含不同颜色随机区域的简单图像。但是,结果会根据请求的最终颜色数量和虚拟像素设置(见上文)而有很大差异。在这个实验中,我有两个选择作为初始随机图像。一个分形等离子体图像和一个随机噪声图像随机图像本质上会生成一个图像,该图像(使用“tile” “-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
颜色数量 边缘 镜像 平铺 白色 黑色
2 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
3 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
4 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
5 [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
前三个图像对颜色“斑点”如何与图像边缘交互具有非常特定的影响。“Edge”和“Mirror”倾向于导致颜色以 90 度角连接边缘。“Random”或“Dither”设置具有类似但更强的颜色斑点与图像边缘的连接,尽管两者也都会在靠近图像边缘的地方引入一些锐利的边缘效果。可能需要第二个模糊量化循环来清理和平滑斑点的边缘。“Tile”设置倾向于允许斑点环绕图像。但是,由于源等离子体图像本身不可平铺,因此结果是在矩形边缘附近发生一般的颜色变化。如果使用可平铺的随机图像作为源,则颜色斑点将完全忽略图像的边界。通过使用“White”或“Black”背景虚拟像素设置,颜色斑点倾向于集中在图像主体中。这种“居中”效果的程度取决于原始随机图像相对于所用“背景颜色”的差异程度。“-blur”的大小基本上会影响斑块的大小和平滑度。小的模糊会产生许多小斑点,大的模糊(如我们在上面使用的)会产生单个更圆形的色斑。
您还可以通过使用不同的颜色量化颜色空间来生成完全不同的颜色和交互。例如,这里我重复了上面最后一个示例(减少到 5 种颜色),但使用了一些更不常用的“-quantize”颜色空间进行颜色选择。(参见颜色量化和颜色空间
颜色空间 边缘 镜像 平铺 白色 黑色
RGB [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
YIQ [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
HSL [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
XYZ [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
OHTA [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
请记住,以上所有图像均是从相同的随机源图像生成的。您看到的不同效果是减少图像中颜色数量的不同方式的结果。您可以看到“-virtual-pixel”设置定义模糊在图像边界之外的区域中看到哪些像素颜色对颜色区域的形状有很大影响。

注释参数用法

IM 版本 6 提供了一个用于文本绘制的新命令行选项“-annotate”,它绕过了旧的“-draw”方法来直接使用 Annotate() API。这为命令行用户提供了一些新功能。在此示例中,我选择了 Arial Black 字体,因为它具有直线字体,因此旋转应该非常清晰。

    magick -font ArialB -pointsize 24 -gravity center \
            -size 55x55 xc:white -annotate 0x0+0+0 'Text' \
            annotate_source.jpg
[IM Output]
此选项的格式为...
  -annotate {SlewX}x{SlewY}+{X}+{Y} 'Text String' 
上述XY偏移量是将要绘制的带注释文本的重力影响位置。但是,SlewXSlewY表示一种旋转形式。如果这两个值相同,则执行正常的旋转。但是,如果它们不同,则可能会产生一些非常有趣的效果。
[IM Output]
如您所见,一些参数导致没有绘制任何文本,基本上是在文本将全部在一行中绘制时。这是可以预料的。但是,您可以看到我们可以将文本翻转、折叠、旋转、斜体化,以各种方式进行绘制。一个非常有用的图像操作符。

拼接:创建新的图像操作符

就在 ImageMagick 版本 6 首次发布后,针对一个问题展开了讨论。这个问题涉及在图像中间添加额外的空间(行和列)。以下示例是在此讨论中产生的复杂命令集,使用了 IM 版本 6 的强大功能,并详细说明了应该执行的操作。从此示例中创建了“-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 Output]
在上面,我们将玫瑰分成许多垂直切片,然后将间隔图像插入该序列,然后再将它们全部重新组合在一起。基本上,我们在玫瑰图像中添加了一列垂直像素。然后用修改后的图像替换我们的原始图像,我们重复了相同的操作,但这次是水平方向。对工作图像进行一些清理,我们就完成了。此示例还突出显示了邮件列表中新的有序命令行处理和版本 6 ImageMagick 的图像序列操作的有用性。在 IM 的早期版本中,这需要大量单独的命令和临时图像才能获得相同的结果。

边框、框架和 BorderColor 的使用

存在一个争论,即“-bordercolor”应该仅用于使用“-border”或“-frame”向图像添加边框。也就是说,许多用户认为它不应该用于设置具有透明度的图像后面的背景。例如,在 IM 下,这会将星形图像的透明区域设置为“-bordercolor”,并完全忽略“-background”颜色设置。

  magick star.gif -bordercolor LimeGreen   -background Gold \
                   -border 10       star_border.gif
[IM Output]
使用“-bordercolor”设置透明图像背景的主要原因是,这使得“magick montage”在给定一组可能包含透明度的随机图像时以一种不错的方式输出,而用户无需进行最少的设置。

    magick montage star.gif  -frame 6  -geometry '64x64+5+5>' star_montage.gif
[IM Output]
如果保留了透明度,则上面的“magick montage”结果将看起来不那么好。
这并不意味着在使用“-border”或“-frame”操作符时无法保留图像的透明度。这仅仅意味着您需要提供额外的“-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 Output]
[IM Output]
有关在添加“-border”或“-frame”的同时保留图像透明背景的更多信息,请参阅添加边框。对于“magick montage”,请参阅montage 背景和透明度处理示例。有人建议的另一种方法是在这些操作符中将图像区域背景设置为“-background”颜色,但这会干扰其在“magick montage”中的使用。当然,您始终可以在添加任何额外的框架或边框之前自己删除图像的透明度。在这种情况下,“-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 Output]
使用“-compose”设置保留透明度,而不是让边框保留透明度并导致其他问题,这要容易得多。对于新用户来说,这可能并不明显,但这就是这些示例页面存在的意义。

列表操作符测试

以下所有命令都应生成完全相同的图像,但所有图像的生成方式略有不同,演示了新的 IM 版本 6 图像列表操作符

  magick eye.gif news.gif  storm.gif  +append  list_test_01.gif
[IM Output]

  magick \( \) eye.gif news.gif  storm.gif  +append  list_test_02.gif
[IM Output]

  magick eye.gif news.gif  storm.gif \( \) +append  list_test_03.gif
[IM Output]

  magick \( eye.gif news.gif  storm.gif \) +append  list_test_04.gif
[IM Output]

  magick \( eye.gif news.gif  storm.gif  +append \) list_test_05.gif
[IM Output]

  magick eye.gif \( news.gif storm.gif +append \) +append list_test_06.gif
[IM Output]

  magick \( eye.gif news.gif +append \) storm.gif +append  list_test_07.gif
[IM Output]

  magick \( storm.gif -flop \) \( news.gif -flop \) \( eye.gif -flop \) \
          +append -flop  list_test_08.gif
[IM Output]

  magick \( eye.gif -rotate 90 \) \( news.gif  -rotate 90 \) \
          \( storm.gif -rotate 90 \) -append  -rotate -90   list_test_09.gif
[IM Output]

  magick eye.gif tree.gif news.gif storm.gif   -delete 1 \
          +append list_test_10.gif
[IM Output]

  magick eye.gif tree.gif news.gif storm.gif  -delete -3 \
          +append list_test_11.gif
[IM Output]

  magick eye.gif news.gif storm.gif tree.gif   +delete \
          +append list_test_12.gif
[IM Output]

  magick news.gif storm.gif eye.gif  +insert  +append list_test_13.gif
[IM Output]

  magick eye.gif storm.gif news.gif  -insert 1  +append list_test_14.gif
[IM Output]

  magick news.gif eye.gif storm.gif   -swap 0,1  +append list_test_15.gif
[IM Output]

  magick storm.gif news.gif eye.gif   -swap 0  +append list_test_16.gif
[IM Output]

  magick eye.gif storm.gif news.gif   +swap  +append list_test_17.gif
[IM Output]

  magick eye.gif storm.gif news.gif   \( -clone 1 \) \
          -delete 1   +append list_test_18.gif
[IM Output]

  magick eye.gif -negate \( +clone -negate \) news.gif  storm.gif \
          -delete 0   +append list_test_19.gif
[IM Output]

  magick storm.gif news.gif eye.gif \( -clone 2,1,0 \) \
          -delete 2,1,0   +append  list_test_20.gif
[IM Output]

  magick storm.gif news.gif eye.gif \( -clone 2-0 \) \
          -delete 0-2   +append  list_test_21.gif
[IM Output]

  magick {balloon,medical,present,shading}.gif  -delete 0--1 \
          {eye,news,storm}.gif   +append  list_test_22.gif
[IM Output]

  magick balloon.gif -delete 0,0,0,0,0,0,0,0,0 \
          eye.gif news.gif  storm.gif  +append  list_test_23.gif
[IM Output]

  magick eye.gif balloon.gif news.gif storm.gif \
          -delete 1,1,1,1,1   +append  list_test_24.gif
[IM Output]

  magick {balloon,medical,present,shading}.gif {eye,news,storm}.gif \
          -delete 0--4   +append   list_test_25.gif
[IM Output]

  magick eye.gif news.gif storm.gif \
          -delete 0--4   +append   list_test_26.gif
[IM Output]

  magick storm.gif news.gif eye.gif -reverse +append  list_test_27.gif
[IM Output]