作者:Anthony Thyssen,<A.Thyssen@griffith.edu.com>
添加注释 -- ImageMagick 示例 - ImageMagick 图像库

ImageMagick 示例 --
添加注释到图像

索引
ImageMagick 示例前言和索引
为图像添加标签 (为图像添加标签的技术)
图像叠加 (将图像彼此叠加和合并)
水印 (添加注释以进行版权保护)
文本和图像定位方法
本文档介绍了使用文本或其他图像为大型图像添加注释的各种方法。注释可以是醒目的,也可以是微妙的。添加图像注释的原因多种多样,但通常是为了
  • 用有关图像内容的信息标记图像。
  • 指出或突出显示图像的某个方面。
  • 将版权或徽标添加到图像中,作为一种版权保护形式。
ImageMagick 提供了许多执行这些操作的方法,但并非所有方法都易于从手册中自行发现。本页面试图介绍常用的方法。许多特定方法在其他示例页面上进行了更详细的讨论。如果您有兴趣为 GIF 动画添加注释或水印,建议您先阅读本文档,然后跳转到 为 GIF 动画添加注释,以帮助您入门。

为图像添加注释

为图像添加标签的基本问题是,无论图像如何,文本都可读。以下展示了许多方法,这些方法中的大多数都可以扩展以执行更复杂的任务。在这些示例中,我将自己限制在 ImageMagick 的默认字体。建议您使用不同的字体和字号,以适应您要实现的目标。

在图像下方(或上方)添加标签

附加标签 现在可以使用中心对齐,从 IM v6.4.7-1 开始,因为 图像追加 现在遵循重力设置,用于对齐目的。

  magick dragon.gif   -background Khaki  label:'Faerie Dragon' \
          -gravity Center -append    anno_label.jpg
[IM Output]
通过重新排列图像,您可以将标签附加到图像上方。

  magick dragon.gif   -background Orange  label:'Faerie Dragon' \
          +swap  -gravity Center -append    anno_label2.jpg
[IM Output]
拼接和绘制 是添加额外空间以允许我们在图像中绘制/添加标签的非常简单的方法。

  magick dragon.gif \
          -gravity South   -background Plum   -splice 0x18 \
          -annotate +0+2 'Faerie Dragon'   anno_splice.gif
[IM Output]
相同的方法可用于在图像上方绘制标签,只需将“South”的重力设置替换为“North”。很简单!

  magick dragon.gif \
          -gravity North   -background YellowGreen  -splice 0x18 \
          -annotate +0+2 'Faerie Dragon'   anno_splice2.gif
[IM Output]
除非作为更复杂绘图功能的一部分,否则不再建议使用“-draw”运算符直接绘制到图像上。有关其他文本绘制方法和技术的更多详细信息,请参阅有关 文本到图像处理 的部分。
使用 Montage 添加标签 ImageMagick 中的 montage 命令经常被用户忽略,因为它只适用于创建整个图像目录的显示。它确实提供了一种非常简单的方法来为图像添加标签。

  montage -label "Faerie Dragon"  dragon.gif \
          -geometry +0+0 -background Gold anno_montage.jpg
[IM Output]
Montage 还可以为您的图像添加框架和其他内容,因此这种类型的标记具有许多超出简单图像标记的额外可能性。

  montage -label "Faerie Dragon" dragon.gif \
          -font Candice -pointsize 15 \
          -frame 5  -geometry +0+0 anno_montage2.jpg
有关使用 montage 的更多信息,请参阅 Montage,图像阵列
[IM Output]
使用 Polaroid 添加标签 使用 montage 的另一种方法是使用 Polaroid 图像变换 生成一个相当花哨的带注释图像。


magick -caption "Faerie Dragon" dragon.gif -gravity center \ -background black +polaroid anno_polaroid.png
警告,此图像被扭曲(弯曲和旋转)并具有一定随机性,因此最终图像大小可能会发生变化,除非禁用旋转。它还包含复杂的阴影和透明效果,因此使用了 PNG 格式图像来保存结果图像。
[IM Output]
您可以通过使用“超级采样”技术来减少旋转造成的最终图像中的“模糊度”。有关此内容的示例,请参阅 Polaroid 图像变换

在图像本身的顶部添加标签...

直接在图片上写文本的问题是,您无法确定所选颜色的文本是否可读。要绘制到的图像可能是黑色、白色或彩虹色。
带轮廓的标签:最简单的方法是用轮廓绘制字符串,以将文本与图像区分开来。但是,由于“-stroke”字体设置会向内和向外添加字体厚度,从而降低其效果(有关更多信息,请参阅 Stroke 和 StrokeWidth。用背景轮廓绘制字体的更好方法是两次绘制文本。

  magick dragon.gif -gravity south \
          -stroke '#000C' -strokewidth 2 -annotate 0 'Faerie Dragon' \
          -stroke  none   -fill white    -annotate 0 'Faerie Dragon' \
          anno_outline.jpg
[IM Output]
如您所见,它确实有效,但效果不佳。它在较粗的字体上效果更好,而不是默认的“Times”或“Arial”字体。有关此技术的更多详细信息,请参阅 厚笔画复合字体
绘制暗淡框:使带注释文本更清晰的更经典的方法是“暗淡”文本将要添加的区域中的图像,然后用相反的颜色绘制文本。例如...

  magick dragon.gif \
          -fill '#0008' -draw 'rectangle 5,128,114,145' \
          -fill white   -annotate +10+141 'Faerie Dragon' \
          anno_dim_draw.jpg
[IM Output]
此方法效果很好,但如您所见,我决定在这个示例中不使用“-gravity”来放置文本,因为暗淡的矩形无法使用重力进行定位(这在将来可能会改变)。此外,其大小和位置可能取决于图像和最终文本大小,这可能需要一些额外的数学计算。
底色框:与其尝试自己绘制背景框,不如让 ImageMagick 对框使用“底色”。请参阅 文本底色框。文本“底色”(如库 API 中所用)可以使用命令行上的“-undercolor”选项指定。

  magick dragon.gif  -fill white  -undercolor '#00000080'  -gravity South \
          -annotate +0+5 ' Faerie Dragon '     anno_undercolor.jpg
[IM Output]
如您所见,它比自己绘制暗淡的框要简单得多,尽管建议在绘制文本的开头和结尾处添加额外的空格,以稍微填充框。
复合标签:更理想的解决方案是预先准备一个文本图像,然后将其作为图像叠加。在这里,我们在半透明背景上创建一个简单的标签,然后将其叠加。

  magick -background '#00000080' -fill white label:'Faerie Dragon' miff:- |\
    magick composite -gravity south -geometry +0+3 \
              -   dragon.gif   anno_composite.jpg
[IM Output]
最后一种技术有一些明显的优势。暗淡的框可以调整大小以适合标签,并且可以使用“-gravity”将其正确定位,而无需了解要添加到的图像或所使用的绘制字体。
此外,您不仅限于使用简单的暗淡框。相反,您可以预先准备非常复杂的字体图像,这样您就可以多次应用它,或者根据图像的特定情况即时生成。几乎所有 复合字体效果 样式也对您可用,允许您使您的文本添加变得非常令人兴奋且专业。自动调整大小的标题:随着 IM v6.3.2 的发布,“caption:”现在可以自动调整文本的大小,使其最适合特定大小的框。
但是,要充分利用它进行叠加,您确实需要了解要添加注释的图像的宽度。在这里,我收集这些信息,然后创建一个标题并将其叠加,以便文本自动调整大小以最适合提供的空间,并进行换行。

  width=`identify -format %w dragon.gif`; \
  magick -background '#0008' -fill white -gravity center -size ${width}x30 \
          caption:"Faerie Dragons love hot apple pies\!" \
          dragon.gif +swap -gravity south -composite  anno_caption.jpg
[IM Output]
此技术非常适合将图像注释叠加到图像上,尽管在命令行上这样做有其自身的问题,因为您正在创建一个新图像,而不是为旧图像添加注释。有关此问题的解决方案,请参阅 用户定义的选项转义 花式标签:作为最后一个示例,我将使用一个花哨的 柔和轮廓字体 创建的文本字符串叠加,以确保它保持可见,但不会为注释创建矩形框。

  magick -size 100x14 xc:none -gravity center \
          -stroke black -strokewidth 2 -annotate 0 'Faerie Dragon' \
          -background none -shadow 100x3+0+0 +repage \
          -stroke none -fill white     -annotate 0 'Faerie Dragon' \
          dragon.gif  +swap -gravity south -geometry +0-3 \
          -composite  anno_fancy.jpg
[IM Output]
如果您计划将相同的标签(例如版权信息)合成到许多图像中,最好先单独生成标签,然后使用“mogrify”命令将该标签合成到每个图像中。上述“-geometry +0-3”偏移用于将合成叠加放置更靠近边缘,因为此图像的柔和模糊轮廓通常大于需要。
所有上述示例当然都应根据您的具体要求进行调整。不要像羊群一样,盲目跟随别人。尝试一下,让您的网站或程序与众不同。更重要的是,将其告诉 IM 社区。
FUTURE: select the black or white color based on the images relative
intensity.  This uses a number if very advanced techniques.

  magick input.jpg  -font myfont -pointsize 25 \
      \( +clone -resize 1x1  -fx 1-intensity -threshold 50% \
         -scale 32x32 -write mpr:color +delete \)  -tile mpr:color \
       -annotate +10+26 'My Text'              output.jpg

Explanation:  Copy of image is resized to 1 pixel to find the images
average color.  This is then inverted and greyscaled using -fx, then
thresholded to either black or white, (as appropriate).
This single color pixel is now scaled to a larger tiling image, and
saved into a named memory register (mpr:).

The image is then used to set the fill tile, for the annotated text.
Their is however no simple method (at this time) to set the outline -stroke
color of the draw text to its inverse.

Other techniques are to use some text as a 'negate image' mask, or even a color
burn or color dodge compose operation, to distort the image with the text.


图像叠加

ImageMagick 中的“magick composite”命令和“-composite”图像运算符提供了将图像以各种方式放置在其他图像顶部的主要方法。这些方法的详细信息在 Alpha 合成 示例页面中给出。但是,还有更高层的运算符也使用图像的 Alpha 合成。这些包括 图像分层,以及本示例页面后面的 使用重力定位图像。compose 的默认合成方法是“Over”,它只是将叠加图像叠加到背景图像上,处理透明度就像您期望的那样。背景图像还决定结果的最终大小,无论叠加放置在哪里(使用“-geometry”选项)。无论叠加是在中间、从背景图像上半途而废,还是远远离开,输出图像都与背景图像大小相同。图像的几何位置也会受到“-gravity”的影响,因此叠加图像的定位可以相对于九 (9) 个不同的位置定义。请参阅下面的“定位图像和文本”。除了 compose 叠加的“-geometry”之外,单个图像还可以具有页面或画布信息(使用“-page”和“-repage”选项设置),这些信息可能会影响图像的最终位置。但是,此特定于图像的信息不受“-gravity”的影响。继续示例...叠加 可能是最常见的图像注释形式,并且非常容易执行。在这里,我在准备好的按钮框架的中间叠加了一个 32x32 城堡图标。

  magick composite -gravity center  castle.gif  frame.gif  castle_button.gif
[IM Output]  + [IM Output] ==> [IM Output]
你也可以精确地定位子图像。这里我们设置一只手来指出小仙龙的小爪子。

  magick composite -geometry +31+105  hand_point.gif dragon.gif \
            dragon_claw_pointed.jpg
[IM Output]  + [IM Output] ==> [IM Output]
图像在背景上的绘制方式由“-compose”设置控制。上面使用的默认值为“-compose over”,它只是将图像叠加在背景上。大多数其他提供的合成方法除了在非常特定的情况下外,不太实用,但这里有一些。有关此设置及其效果的更多详细信息,请参阅 Alpha合成Bumpmap 是一种棘手的合成方法,它基本上根据叠加图像的亮度来使背景图像变暗。叠加图像中任何白色的部分都被视为透明的,而任何黑色的部分都会在输出图像中变成黑色。这有点像用叠加图像作为墨水印章,这是一个很好的描述这种操作的方式。提示:用凹凸贴图叠加最适合浅色图像。因此,您可能需要在使用之前准备凹凸贴图图像。在这里,我们在使用“-compose bumpmap”将龙图像绘制在纸张卷轴图像上之前调整了龙图像的大小。

  magick composite \( dragon.gif -resize 50% \) scroll.gif \
            -compose bumpmap -gravity center   dragon_scroll.gif
[IM Output]  + [IM Output] ==> [IM Output]
凹凸贴图也可用于对图像设置整体效果,在本例中,我们在龙的上面平铺浅色的背景图案。请记住,凹凸贴图图像被视为灰度图像,因此叠加图像中的任何颜色都会丢失。

  magick composite -compose bumpmap  -tile rings.jpg \
            dragon.gif  dragon_rings.jpg
[IM Output]  + [IM Output] ==> [IM Output]
上面的“-tile”选项仅适用于使用“magick composite”命令的合成操作。在“magick”中,您必须使用“tile:”图像生成器,并使用“-size”来指定范围。当然,您可以使源图像叠加比您要叠加的背景图像更大,因为结果将是背景或目标图像的大小。
Multiply 合成方法以其合并具有白色背景的两个图像(如文本页面)的能力而闻名。与 'bumpmap' 合成方法不同,它不会预先将叠加图像转换为灰度。

  mesgs PictureWords |\
      magick -pointsize 18 text:-  -trim +repage \
              -bordercolor white -border 10x5   text.gif
  magick composite -compose multiply -geometry +400+3 \
            paint_brush.gif  text.gif  text_multiply.gif
[IM Output]  + [IM Output] ==> [IM Output]
旁注:上面生成“text.gif”的复杂命令只是为了创建一个典型的纯文本图像,“mesgs”命令只是输出一个特定的引用,就像“fortune”所做的那样,但有更多的控制权。这种方法在很多情况下非常有效,但通常只有在其中一个(或两者)图像基本上是黑色(或灰度)并在白色背景上的情况下才有效。如果两个图像都包含彩色区域,则您可能会得到不寻常的结果。换句话说,此技术非常适合在白色(或相当浅色的)图像(例如打印或扫描页面的图像)上叠加线图、图表或文本图像。

水印

水印是一项重要的工作,因为它提供了一种将图像标记为属于某个公司或网站的方法。不幸的是,这涉及以某种方式破坏图像,从而损害图像本身。水印的基本目标是
  • 无论图像的颜色是浅色还是深色,标记都应该清晰可见。
  • 它应该难以删除。
  • 并且它不应该对观看者造成太多困扰。
所有这些因素都是冲突的,这也是水印如此难以做好的一大原因。

使用符号添加水印

最简单、也是最令人讨厌的水印形式之一,就是将一个非常小的特定图像放置在要加水印的图像上的某个位置。这里,我们生成一个图像(使用“logo:”),我们想用一个小“眼睛”符号对其进行水印。

  magick logo: -resize x180  -gravity center  -crop 180x180+0+0  logo.jpg
  magick composite -geometry +160+13 eyes.gif   logo.jpg  wmark_symbol.jpg
[IM Output]  + [IM Output] ==> [IM Output]
对于放置小图像的最佳想法是添加它,使其看起来像是原始图像的一部分。在上面,我添加了“眼睛”图像,使其看起来几乎像是巫师帽的一部分(你也不希望它过于融入图像)。因此,这种技术需要人工干预,这使其无法完全自动化。小图像也很难删除,因为它会完全破坏它叠加的部分图像。如果做得好的话,很难注意到,除非你专门在寻找它。我在网上很多地方都看到了它被很好地使用。一个网站使用了一个小的匕首状符号。从该网站盗取的图像变得非常明显,当我发现其他网站上发现的图像上也有相同的匕首符号时。

用水印文本

只在图像上绘制文本也是一种简单的水印方式,上面所有 在图像上标记 的示例都可以用作一种水印类型。但是,为了正确地执行此操作,您应该使用两种不同的颜色,以防止文本在绘制在不同颜色背景上时消失。因此,应该使用某种 复合字体效果

  magick logo.jpg  -font Arial -pointsize 20 \
          -draw "gravity south \
                 fill black  text 0,12 'Copyright' \
                 fill white  text 1,11 'Copyright' " \
          wmark_text_drawn.jpg
这效果很好,而且可以自动化,但它过于大胆,不能用作好的水印,因为它在图像中过于显眼。
[IM Output]
但是通过做一些准备工作,可以创建一个具有透明背景的图像,这将不那么引人注目。有关用于生成水印文本的步骤的详细信息,请参阅 字体蒙版。另外 蒙版图像 中的蒙版示例可能对您理解有所帮助。

  magick -size 300x50 xc:grey30 -font Arial -pointsize 20 -gravity center \
          -draw "fill grey70  text 0,0  'Copyright'" \
          stamp_fgnd.png
  magick -size 300x50 xc:black -font Arial -pointsize 20 -gravity center \
          -draw "fill white  text  1,1  'Copyright'  \
                             text  0,0  'Copyright'  \
                 fill black  text -1,-1 'Copyright'" \
          -alpha off stamp_mask.png
  magick composite -compose CopyOpacity  stamp_mask.png  stamp_fgnd.png  stamp.png
  magick mogrify -trim +repage stamp.png
[IM Output]
现在我们有了水印字体,可以将其应用到我们的图像上了……

  magick composite -gravity south -geometry +0+10 stamp.png  logo.jpg \
            wmark_text_stamped.jpg
如您所见,水印不像以前那样大胆,甚至使用的是灰度而不是纯白色和黑色。即便如此,它仍然非常显眼,无论背景是什么。 复合字体效果 页面详细介绍了许多在这种情况下可用的字体样式,而不会压倒要加水印的图像。
[IM Output]
您也可以将文本平铺在整个图像上。这里,我们还通过使用命令的“管道”,避免了对中间图像的需要,其中一个命令的输出是下一个命令的输入。

  magick -size 140x80 xc:none -fill grey \
          -gravity NorthWest -draw "text 10,10 'Copyright'" \
          -gravity SouthEast -draw "text 5,15 'Copyright'" \
          miff:- |\
    magick composite -tile - logo.jpg  wmark_text_tiled.jpg
这利用了这样一个事实:图像(如照片,而不是图表)通常会有一些区域,在这些区域中,平铺的测试字符串将是可见的。您可能希望将文本设为半透明,以便您自己的水印(例如,使用半透明的灰色,如“'#80808080'”)。您可能还想记住这种平铺技术以及以下适当的水印技术。
[IM Output]

使用图像添加水印

ImageMagick 还提供了一些选项,这些选项专门用于在更大的区域上进行更微妙的水印。这通常是您“水印”图像时更常见的用法。右侧是一个“水龙”图像,我将用它来进行这些演示。它具有一定的透明度,我用它来检查 IM 是否对透明度做了正确的事情,避免结果出现任何可怕的“方形”外观。 [IM Output]
在 IM 6 版之前,选项“-watermark”和“-dissolve”在处理叠加图像的 alpha 通道(透明度)时出现了问题,产生了非常奇怪的效果。
Watermark 合成原本是为了给图像加水印,虽然它有效,但它往往只适用于纯白色和黑色叠加图像,会产生难看的边缘伪影。

  magick composite -watermark 30% -gravity south \
            wmark_image.png  logo.jpg    wmark_watermark.jpg
有关此选项的更多详细信息,请参阅 水印选项使用 页面。
[IM Output]
Dissolve 被我及其他人发现效果更好。

  magick composite -dissolve 25% -gravity south \
            wmark_image.png   logo.jpg  wmark_dissolve.jpg
这效果非常好,但水印的一部分会在具有纯白色和黑色像素的图像上消失。也就是说,白色在白色和黑色在黑色上的溶解在最终图像中将不可见。由于这两种颜色非常常见,因此最好对水印进行一些额外的预处理,以便它使用各种灰度而不是纯白色和黑色。(见下面的“灰度溶解”)
[IM Output]
有关此选项的更多详细信息,请参阅 Dissolve 选项使用 页面。
Tiled: 您也可以将水印平铺在背景图像上,而不是只将其添加到一个位置。只需将您的重力位置替换为“-tile”即可。当然,在这种情况下,您可能希望使水印不那么显眼。

  magick composite -dissolve 15 -tile \
            wmark_image.png   logo.jpg  wmark_tiled.jpg
[IM Output]
Greyed Bumpmap: 为了正确使用 bumpmap 作为水印,图像需要一些准备工作,以使白色和黑色都变成较浅的灰色范围,使用 灰度调整 技术。如果不这样做,结果会非常非常粗犷。

  magick wmark_image.png  -fill Gray91 -colorize 80  miff:- |\
  magick composite -compose bumpmap -gravity south \
            -  logo.jpg    wmark_bumpmap.jpg
[IM Output]
将 bumpmap 用作水印的最大问题是该操作只会使图像变暗。因此,这种技术对于非常暗的图像来说是相当无用的。
Greyed Dissolve: 相同的预处理技术也适用于溶解方法,因此水印图像的白色部分会在白色背景上略微变暗,同样地,水印图像的黑色区域会在图像的黑色部分上略微变亮。

  magick wmark_image.png  -fill grey50 -colorize 40  miff:- |\
  magick composite -dissolve 30 -gravity south -  logo.jpg wmark_dissolve_grey.jpg
[IM Output]
我认为这几乎是水印的理想选择,满足了所有要求。不过,我还会进一步调整最终的溶解度,使水印不那么显眼。
Tiled Greyed Dissolve: 这与上面完全相同,只是在图像上平铺,并且溶解度值更低。

  magick wmark_image.png  -fill grey50 -colorize 40  miff:- |\
  magick composite -dissolve 15 -tile  -  logo.jpg wmark_dissolve_tile.jpg
[IM Output]
magick composite”命令不知道如何处理多图像文件,例如动画。但是,其他方法允许您执行此操作。有关注释和叠加多图像文件的示例,请参阅 修改动画、注释

使用重力定位图像和文本

事态的“重力”

如您在上面所见,能够在更大的图像中定位图像和文本与其他任何事情一样重要。当然,“-gravity”设置是其中最重要的方面之一。
在 ImageMagick 邮件列表中,Tim Hunter 宣称
重力会让你抓狂,直到你掌握它为止。
我完全同意这种观点。
重力仅在以下情况下适用……
  • 任何涉及“几何”设置的操作,例如“-crop”和“-geometry”图像的定位 Alpha合成,包括 多图像分层合成
  • 它也用作各种文本到图像生成器(例如“label:”)的文本对齐方式的指定方法,以及各种文本到图像生成器(例如“caption:”)的文本对齐方式。
  • -annotate”文本绘制运算符也使用它进行文本定位和对齐。
  • 最后,它被“-draw”方法的 'text' 和“image' 方法使用,并且仅限于这些方法。
但是,“-gravity用于
  • 任何图像列表或图层运算符,例如“-mosaic”、“-flatten”和大多数“-layers”方法,尤其是在 GIF 动画中。所有这些操作都使用图像在更大的虚拟画布上的偏移量(使用“-page”、“-repage”元数据设置设置)来定位图像。此类偏移量始终相对于图像虚拟画布的左上角。在这种方法中,不会使用对“-gravity”的任何理解。
  • 任何其他“-draw”方法都不会使用“-gravity”进行定位。它也不太可能这样做,因为“-gravity”在 IM 遵循的 SVG 草案中没有定义,用于这些低级函数。
这一切意味着什么?首先也是最重要的是,它定义了“-geometry”用于将叠加文本和图像相对于图像边缘、边和中心定位的原点,而无需用户知道图像的实际大小。这是它的主要功能。其次,它定义了叠加对象(文本或图像)相对于所定义重心点的水平和垂直对齐方式。例如,使用“East”重心,文本或图像将放置在定义点的右侧(右对齐)。严格来说,对齐方式应该与“-gravity”设置分开,尽管两者密切相关,但 IM 目前将两者合并为一个设置。目前正在推动将这两个方面分开,这样如果“justification”设置未定义,它将回退到使用当前“-gravity”设置。如果您发现需要此功能,请通过邮件列表向 Cristy 提出请求。我相信,如果足够多的用户要求,它最终会被实现。

使用重力定位图像

以下是如何使用重力将图像定位在背景上的示例。

  magick composite label:Default                      rings.jpg gravity_default.jpg
  magick composite label:Center    -gravity center    rings.jpg gravity_center.jpg
  magick composite label:South     -gravity south     rings.jpg gravity_south.jpg
  magick composite label:East      -gravity east      rings.jpg gravity_east.jpg
  magick composite label:NorthEast -gravity northeast rings.jpg gravity_northeast.jpg
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
请注意,图像的实际位置也根据“-gravity”设置进行对齐。也就是说,“South”重心将使图像居中在较大图像的底部,但在重心点之上。这在后面的文本旋转中会变得更加重要。要记住的另一件事是,任何“-geometry”设置指定的定位都是相对于重心放置图像的定位。不仅如此,定位方向也会改变,使定位方向指向内部。例如,“-gravity South -geometry +10+10”将使标签图像进一步进入背景。也就是说,几何定位的 Y 方向被反转,而 X 方向保持不变。

  magick composite label:Default   -geometry +10+10 \
            rings.jpg gravity_default_pos.jpg
  magick composite label:South     -geometry +10+10 -gravity south \
            rings.jpg gravity_south_pos.jpg
  magick composite label:NorthEast -geometry +10+10 -gravity northeast \
            rings.jpg gravity_northeast_pos.jpg
[IM Output] [IM Output] [IM Output]
您还可以将“-gravity”与“-draw image”一起使用,以单个命令处理多个图像。

  magick rings.jpg \
          -gravity Center     -draw "image Over     0,0 0,0 'castle.gif'" \
          -gravity NorthEast  -draw "image Bumpmap  0,0 0,0 'castle.gif'" \
          -gravity SouthWest  -draw "image Multiply 0,0 0,0 'castle.gif'" \
          gravity_image.jpg
[IM Output]
您现在还可以使用“-composite”将图像叠加到背景上……

  magick rings.jpg \
          -gravity Center     castle.gif  -compose Over     -composite \
          -gravity NorthWest  castle.gif  -compose Bumpmap  -composite \
          -gravity SouthEast  castle.gif  -compose Multiply -composite \
          gravity_image2.jpg
[IM Output]
有关上面使用的“-compose”设置的更多详细信息,请参见 Alpha 合成。有关将多个图像组合和叠加成一个单个图像的其他方法,请参见 IM 示例部分 多图像图层

使用重力定位文本

也就是说,对于图像来说很好,但是直接在图像上绘制文本呢?嗯,图像的基本效果也适用于此。如上所述,重力也会影响使用“-draw”的“text”方法或更好的“-annotate”文本绘制操作符绘制文本的定位。

  magick rings.jpg -resize 120x120  \
          -gravity northwest  -annotate 0 'NorthWest' \
          -gravity east       -annotate 0 'East' \
          -gravity center     -annotate 0 'Center' \
          -gravity south      -annotate 0 'South' \
          -gravity northeast  -annotate 0 'NorthEast' \
          gravity_text.jpg
[IM Output]
定位图像和文本之间存在一个非常重要的区别。如果您绘制一个文本字符串,而没有定义任何形式的“-gravity”,该字符串将相对于字体的“基线”绘制。
例如,让我们实际做一下……

  magick rings.jpg -annotate 0 'String' gravity_text_none.jpg
[IM Output]
如果您仔细观察,您将只看到“String”中“g”的小循环尾部在生成图像的顶部边缘可见。字符串的其余部分已绘制在背景图像之外。但是,如果您将“-gravity”设置为“NorthWest”,则文本将被定位,就像它是一个图像一样。也就是说,相对于字体定义的边界框或底色框
例如……

  magick rings.jpg -gravity NorthWest -annotate 0 'String'  gravity_text_nw.jpg
[IM Output]
造成这种区别的原因是为了确保 IM 文本绘制与其他矢量绘制图像格式(如“SVG”)保持兼容。这些格式不使用重力,因此打开重力告诉 IM 在绘制文本时遵循与图像放置相同的规则,而不是矢量图形规则,包括字体的“基线”和文本的“起点”。如果您确实打开了重力,然后希望稍后将其关闭,您可以使用“-gravity none”或“+gravity”将其重置回默认的“无重力”设置。
让我们应用一个文本偏移,并绘制“-gravity”的默认“None”和“NorthWest”参数,这样您就可以看到两种形式之间的密切关系。

  magick rings.jpg \
          -gravity NorthWest -annotate +10+20 'NorthWest' \
          -gravity None      -annotate +10+20 'None' \
          gravity_text_pos.jpg
[IM Output]
虽然在这个示例中可能看不出来,但这两个字符串可以重叠,特别是在“g”和“p”等字母的下垂部分。也就是说,这两个字符串不是由“点大小”单位正确分隔,而是由字体的基线高度分隔。最好的办法是不在自己的图像处理中混合这两种模式。要么使用重力,要么不使用。选择权在你。

使用重力将文本放在左侧边缘

作为最后的示例,以下是将文本实际注释在图像左侧边缘居中的方法。这里的问题是,当您旋转文本时,它会围绕文本“句柄”旋转。不幸的是,这个句柄是在文本旋转之前由重力设置的,因此效果不佳,除非您将自己限制在“居中文本”。 [IM 输出]
例如,以下是一个典型的“第一次尝试”来定位文本,使其位于图像左侧边缘的中心。当然,它失败了,而且非常意外!
 magick rings.jpg \ -gravity West -annotate 90x90+10+0 'String' \ gravity_text_left_fail.jpg 
如您所见,文本被放置在左侧边缘,但只是使起点(预旋转的“句柄”所在位置)居中。造成此问题的原因是,在 IMv7 中,“
-gravity”设置也被直接用于设置文本“对齐方式”(它设置用于定位文本的“句柄”)。有一些用 PerlMagick API 编写的关于重力对旋转文本的影响的动画演示(下载“im_annotation.pl”。我还创建了该程序的 shell 脚本版本,“im_annotation”和“im_annotation_2”。
使此方法起作用的一个技巧是先旋转整个图像,然后使用中心南部!这是一个没有道理的解决方案,但它确实有效。

  magick rings.jpg -rotate -90 \
          -gravity South -annotate +0+2 'String' \
          -rotate 90  gravity_text_left.jpg
[IM Output]
在下面的 使用扭曲定位文本 中显示了另一种方法。

使用 Draw 定位文本

虽然我在上面使用“文本偏移”来定位相对于“-gravity”点的文本,但这不是唯一的方法。另一种方法是使用“-draw translate”选项来定位文本。这样做的优点是,您可以安排在不使用重力效果的情况下定位文本,同时仍然使用重力来“对齐”文本中定位“句柄”。在这些示例中,我添加了一些额外的构造线(这些构造线也不受重力影响)来显示如何从图像的中心点应用定位。带偏移量的文本……

  magick -size 100x100 xc:white -gravity Center \
          -fill cyan  -draw 'line 50,50 70,70' \
          -fill red   -draw 'line 68,70 72,70 line 70,68 70,72' \
          -fill blue  -draw "text 20,20 'Offset'" \
          text_offset.jpg
[IM Output]
带平移的文本……

  magick -size 100x100 xc:white -gravity Center \
          -fill cyan -draw 'line 50,50 70,70' \
          -fill red  -draw 'line 68,70 72,70  line 70,68 70,72' \
          -fill blue -draw "translate 20,20 text 0,0 'Translate'" \
          text_translate.jpg
[IM Output]
如您所见,两者都产生了相同的效果。但由于“-draw text”要求您提供作为其参数一部分的偏移量,因此它更常用于从命令行定位绘制的文本。但是,虽然这两种方法都产生了相同的结果,但当应用文本旋转时,它们会产生完全不同的结果。这主要是因为操作应用的顺序不同。“-annotate”操作符专门设计为使定位旋转文本更容易,方法是专门要求 IM 使用旋转绘制文本,而不是“进行表面扭曲”。用旋转和偏移量注释……

绘制旋转文本

有两种不同的方法可以定位绘制的文本:使用“文本偏移量”或将文本“平移”到最终位置。这两种定位方法在应用旋转时会产生截然不同的结果。造成这种现象的原因很复杂,但本质上涉及 IM 如何进行绘制表面变形。话虽如此,让我们看看如果您使用两种不同的位置旋转一些文本会发生什么。只有偏移量,没有旋转……

  magick -size 100x100 xc:white -gravity Center \
          -fill cyan -draw 'line 50,50 70,70' \
          -fill red  -draw 'line 68,70 72,70  line 70,68 70,72' \
          -fill blue -draw "text 20,20 'None'" \
          rotate_none.jpg
[IM Output]
用偏移量旋转文本……

  magick -size 100x100 xc:white -gravity Center \
          -fill cyan -draw 'line 50,50 50,78' \
          -fill red  -draw 'line 48,78 52,78  line 50,76 50,80' \
          -fill blue -draw "rotate 45 text 20,20 'Offset'" \
          rotate_offset.jpg
[IM Output]
用平移旋转文本……

  magick -size 100x100 xc:white -gravity Center \
          -fill cyan -draw 'line 50,50 70,70' \
          -fill red  -draw 'line 68,70 72,70  line 70,68 70,72' \
          -fill blue -draw "translate 20,20 rotate 45 text 0,0 'Translate'" \
          rotate_translate.jpg
[IM Output]
这实际上是大多数人想要的。虽然偏移旋转可以用于某些特殊效果。请注意,这些绘制表面变形的顺序与它们的给出顺序相反。旋转首先执行,然后平移执行。如果反转“旋转”和“平移”方法,您将获得与普通“文本偏移量”相同的結果,即旋转的偏移量。“-annotate”操作符专门设计为使定位旋转文本更容易,方法是专门要求 IM 使用旋转绘制文本,而不是“进行表面扭曲”。用旋转和偏移量注释……

  magick -size 100x100 xc:white -gravity Center \
          -fill cyan -draw 'line 50,50 70,70' \
          -fill red  -draw 'line 68,70 72,70  line 70,68 70,72' \
          -fill blue -annotate 45x45+20+20 'Annotate' \
          rotate_annotate.jpg
[IM Output]
上面示例的问题是,IMv7 的“-gravity”设置不仅指的是背景图像上的位置,还指的是要绘制的叠加图像中的位置。IMv7 将添加“文本对齐方式”,它指的是叠加位置,作为一个单独的(但相关的)设置,用于重力(背景位置)。

使用 Distort 定位文本

使用SRT 扭曲图像分层,是放置图像(或图像中的文本)的特别好的方法。基本上,它允许您完全控制图像放置的点以及图像相对于该点的排列方式。首先,我们创建一个具有透明背景的“文本图像”,然后简单地将图像“分层”到背景图像上。

  magick rings.jpg -background none label:'Some Text' \
          -flatten  layer_simple.jpg
[IM Output]
如您所见,文本只是添加到图像的左上角。让我们使用扭曲(分层变体)来旋转它——注意使用圆括号来限制我们扭曲的图像!

  magick rings.jpg \( -background none label:'Some Text' \
             +distort SRT 70 \
          \) -flatten  layer_rotate.jpg
[IM Output]
请注意,文本位置没有改变!唯一发生的事情是扭曲围绕中心点(句柄)旋转文本,但相对于“虚拟画布”,该点没有移动。因此,当现在更大的图像被平铺时,它的旋转点“文本图像的中心”没有移动。下一步是移动该句柄,但为此我们需要使用几乎完整的SRT 扭曲参数集。因为我们希望继续使用“中心句柄”,所以我们需要使用一些图像属性百分比转义,或者更具体地说是FX 百分比转义。所以让我们将中心放在背景图像中的“+60+60”处

  magick rings.jpg \( -background none label:'Some Text' \
             +distort SRT '%[fx:w/2],%[fx:h/2] 1 70 60,60' \
          \) -flatten  layer_translate.jpg
[IM Output]
移动“图层图像”的另一种方法是使用重分页操作符。特别是使用“!”标志进行相对移动。由于图层图像的性质,此操作的“句柄”位于左上角。 SRT 扭曲操作符 不仅会使用指定的句柄平移图像,还可以使用亚像素(浮点)位置来定位这两个句柄。也就是说,它可以以亚像素增量将文本扭曲到任何位置,而不会受到大多数其他操作的整数限制。最后一个例子是将旋转 90 度的文本放置在左边缘。这次,文本旋转和定位的句柄将位于文本的中心底部,而不是旋转之前的位置。也就是说,计算出的位置为“%[fx:w/2],%h”。背景图像上的位置也必须计算为中心左边缘(“0,%[fx:h/2]”)。问题在于 SRT 扭曲操作符 在扭曲文本图像时无法访问背景图像。解决方法是在背景图像可用时进行此位置计算,并将其保存到某些“个人设置”中,然后将其添加到扭曲参数中。这种技术将在 从其他图像中提取信息 中详细介绍。以下是结果。首先计算背景图像上的位置。然后扭曲文本图像,使其“句柄”也移动到预先计算的位置。

  magick rings.jpg -set option:my:left_edge '0,%[fx:h/2]' \
          \( -background none label:'Some Text' \
             +distort SRT '%[fx:w/2],%h 1 90 %[my:left_edge]' \
          \) -flatten  layer_on_left.jpg
[IM Output]
my:”字符串可以是任何不与现有前缀冲突的字符串。也就是说,我使用它来保存我的设置,与 ImageMagick 可能用于编码器或特定选项的任何其他设置分开。使用“my:”作为前缀是这种情况下一个不错的选择。百分比转义符纯粹作为字符串替换处理,实际上我们可以将整个扭曲选项生成为一个字符串。唯一的问题是,在设置“my:”设置后,你无法对其进行数学运算。因此,任何数学运算都必须事先完成。这将是 IMv7 中将要考虑的事情,以便 FX 表达式使用 % 转义变量。