ImageMagick 示例 --
绘图
索引
在 IM 中绘图是将新元素添加到现有图像的方法。虽然许多文本绘制内容在 复合字体效果 页面和 图像标注 页面中都有介绍,但本页面重点介绍 "
'
'
您可能还想查看 推入/弹出上下文,了解如何创建旋转的椭圆形。
绘制线条和曲线的更好方法是使用 SVG 路径绘图,它可以更灵活,甚至允许进行 '相对线条绘制'。
最后这两个填充类型操作是目前唯一受 "
如果我移动其中一个控制点,使其 NOT 'reflected' 通过与其连接的 'knot' 从同一个 'knot' 的另一个控制点反射,那么曲线将不连续。
如果再次移动控制点,使其与相关的 'knot' 点匹配,则直线将直接从该点开始,没有 'curve' whatsoever。
如果两个控制点都设置为它们各自的 'knots',则将生成一条直线。
'
不建议您每个 '
但是,在绘制透明和半透明颜色时,这些功能并不相同。这里我们有一个三像素红色图像(放大),第二个或中间像素我们使用了 '
所有 '
但是,正如您在第一个结果中看到的,边缘的一些像素没有被替换。这些像素的颜色与所选像素的颜色并不完全相同,因此被忽略了。添加一个小的 模糊因子 也会包含与原始颜色相似的颜色。如上例二所示。当然,“模糊因子”并不是一个很好的解决方案,因为它不会捕获所有此类边缘像素。这是所有这些“颜色填充”方法的反复出现的问题,并且没有通用的解决方案。如果您想替换特定已知颜色,而不是从图像本身选择颜色,那么可以使用“
用颜色填充区域并非没有问题。颜色可能会泄漏到细小的边界,进入不希望的位置(请参阅 背景图案上的 GIF 作为对此的演示)。或者它可能不会填充到所选区域的边缘(请参阅 抗锯齿和洪水填充问题)。但它确实有效。'
最后一种绘制颜色方法是“
这实际上非常有用,因为它提供了一种简单的方法,可以从现有图像生成纯色(或平铺图像)画布。(请参阅 根据现有图像尺寸调整画布)了解此方法以及其他执行相同操作的方法。未来:使用“
“
请注意,“
看看圆圈的边缘,它们看起来并不真正平滑。您可以看到明显的阶梯效果。那是因为您是在线性 RGB 色彩空间中绘制圆圈的。但您随后保存图像时却认为它实际上是 sRGB 色彩空间!
现在,圆圈的边缘看起来确实平滑圆润,就像它们应该的那样。如果您想正确地执行此操作,我们应该使用色彩空间进行校正。但是,由于 IM 假设 RGB 是保存的默认色彩空间,因此您需要进行一些复杂的处理才能使其正确执行。
要在(IMv7 中)使用真实图像正确绘制(或执行任何“线性”图像处理),您需要先去除任何现有的 gamma,处理图像,然后恢复该 gamma 校正。有关更多详细信息,请参阅 使用色彩空间校正进行调整大小。以下是如何在真实图像上绘制的示例... 首先没有颜色校正(原始),然后有 gamma 和色彩空间校正。
如您所见,通过使用 gamma 或色彩空间校正,线条变得非常平滑,没有锯齿状的“阶梯”锯齿效果,而直接绘制时可以看到这些效果。(您需要一个非常好的显示器才能看到它)
默认设置是“
请注意,从上述示例中可以看出,将“
以下是如何使用非常大的笔触宽度的示例。
请注意,“
有关使用笔触的更多示例,请参阅 复合字体效果。特别注意 气球效果。
您可以使用“
您还可以通过设置“
但是我们用 "
例如,您可能会认为此命令将产生一条非常粗的线。它确实如此,但由于 "
但是,如果描边颜色也被定义,您将获得请求的粗线...
如果 "
当然,当您掌握了这些知识后,您可以像使用字体绘制一样,发挥创意。
在这里,我使用了最细的 "
这产生了非常奇怪的结果,一条由黑色点和灰色线段组成的虚线。这是描边、填充和背景颜色之间奇怪的“颜色拍频”的结果。以下是该线条的放大视图...
请注意,此效果仅出现在倾斜线上,不适用于纯水平线或垂直线,因为反锯齿对这些线没有影响,因此没有“颜色拍频”效果。
在这里,我在放大视图中使用了不同的底层填充颜色,以便您可以看到颜色如何改变最终的拍频。
如您所见,在绘制非常细的线条时,您可以通过使用相同的填充颜色和描边颜色,或者将其中一种颜色设置为 none 来关闭它,从而减少“拍频”。虽然后者是最好的主意,但前者可能更适合您的特定编程需求。请注意,填充线条厚度为“0”。但是描边线条可以具有更大的厚度。它也是一个浮点值!一条 2.5 像素宽的线条是完全有效的。
两个黑色部分(实际上就是绘制的内容)实际上彼此重叠!换句话说,即使我们尝试使用绘制的多边形分别绘制这两个区域,填充区域也比请求的尺寸略大。我还添加了 (加在一起合成) 这两个图像,这样您就可以真正看到绘制的黑色区域的重叠。如果这两个多边形是完美匹配的,则“添加”后的绘图将是纯白色。实际重叠量相当于默认的 "
如您所见,'颜色填充'基本图形的特殊设置在 MVG 中没有直接等效项。也就是说,"-bordercolor" 和 "-fuzz" 因子设置。这些必须在使用 "
您可以在 "-draw" MVG 参数中本地覆盖该全局设置…
但是,在单个 "-draw" MVG 参数中设置的设置仅在该 "-draw" 操作持续期间存在。也就是说,"-draw" 中的设置仅限于该绘制,不会延续到以后的单独 "-draw" 参数。
如果您打算执行大量操作,最好将它们全部放在单个 MVG 字符串中,而不是多个 "-draw" 操作。
'
但是请注意,'
由于对象以相同的方向围绕中心绘制,因此两个闭合循环将围成一个循环值为 2 的区域。因此,'
这意味着您可以通过反转方向来生成对象中的“孔”,以便将对象的“内部”保持在行进方向的同一侧。
无论“
“large”和“sweep”参数尤为重要,因为它们用于确定将以四种方式中的哪一种从起点弧形到该路径组件的终点。
第二个标志“sweep”只是确定弧线应该绘制在直线路径方向的哪一侧。“large”标志用于选择更长的路径,围绕椭圆中心。也就是说,弧线角度将大于 180 度。如果关闭,您将获得较小的“弧线”,不包含椭圆的中心,并且弧线跨越小于 180 度的角度。用 'Z' 闭合一个弧线只是绘制一个最终的直线段。要创建完整的椭圆或圆形,您至少需要两个“弧线”段,从第一个点到第二个点,然后返回到第一个点。两个弧线应该具有相同的“sweep”设置,因此弧线将在不同的侧面,具有不同的行进方向。其中一个弧线应具有“large”设置。
请注意,如果线太长而无法以给定角度适应给定的椭圆大小,则椭圆的大小将被放大以适应该线,椭圆以该线为中心。这意味着,通过使用轴半径的小数字,您只需指定轴长度的比率,并保证直线路径穿过椭圆的中心点。也就是说,路径形成从椭圆的一侧到另一侧的椭圆直径。这并不一定是椭圆的主轴或副轴,只是一个椭圆直径。
当然,使用“
对于在两个点之间居中的完整圆形,请使用…
SVG 对“弧线”的定义还声明,如果两个半径中的任何一个为零,则应该绘制一条直线。因此,任何半径为“
如果您为弧线指定了非常大的半径,并且没有为返回路径指定“large sweep”,则可以在两个点之间创建该半径的透镜形状。
这种类型的弧线是一个关键功能。它允许您非常轻松地为原本是直线的线提供一个小的但明显的曲线。例如,而不是像这样简单的三角形…
您可以使用大半径将每条线替换为一个弧线,使它们略微弯曲。
线的端点没有变化,发生的变化是每个 '
原本看起来像直边三角形的“静态”图形,现在看起来有点像被风吹鼓的帆。如果你真的想让线条完全笔直,而不想把它们转换回真正的线段,你可以使用零弧半径来关闭曲线。因此,弧线不仅适用于生成椭圆和圆形,而且对于绘制直线和略微弯曲的线段也很有用。它是一种非常通用的点到点绘制路径。使用椭圆弧生成分离的曲线线段的一种简单替代方法是使用 二次贝塞尔曲线段。主要区别在于使用单个控制点,而不是圆形半径来定义弧线。这也允许你将弧线偏向线段的一端,但代价是更难生成对称的弧线。当然,你可以“混合搭配”使用两者。 饼图示例 为了完成使用弧线,让我们举一个使用它们来生成圆形扇形的例子。当然,你可能需要使用一些外部三角函数(你高中数学学得怎么样?)来确定所需的最终路径点。
请注意,所有弧线都绘制在“线路径”的左侧,并相应地标记(使用“sweep”标志)。但是,如果弧线覆盖的角度大于 180 度,则需要设置“large”标志。请参见上面的最后一个“金色”组件。还要注意,你应该完全绘制每个部分,即使这意味着你可能需要绘制两次边界线。如果你不这样做,你可能会无法用颜色完全填充该部分,或者填充颜色会覆盖先前绘制的部分轮廓。避免重复多条线的唯一方法是绘制所有填充区域,然后重复以绘制轮廓。也就是说,你需要绘制两次所有内容,确保它们正确匹配。因此,重复轮廓可能是最简单的解决方案。 三次贝塞尔曲线 可以使用定义两个控制点和最终终点的“
连接控制点到该路径段路径上的最终点的线(控制线)基本上定义了曲线通过路径上该点的方向。一条长控制线将产生在该点更平滑的曲线,而一条短线将在该点生成更尖锐的曲线。如果控制点与曲线的点匹配(控制线长度为零),则曲线在该点将具有尖锐的不连续性,就好像只使用直线段一样。作为一个更实际的例子,以下代码片段是从 IM Examples Logo 生成器脚本 中提取的,该脚本创建了 IM Examples Logo 的曲线状飞溅区域。示例中的棘手部分是我将使用的三次贝塞尔曲线路径字符串魔法转换成另一个路径,显示用于生成贝塞尔曲线的控制线。这让我能够看到曲线的控制线角度和长度,从而更容易调整结果。只需要调整一组点即可显示曲线和控制线,从而将错误降到最低。
如果你仔细观察图像,你会发现曲线的开头和结尾有两条控制线指向相反的方向。对于封闭的连续路径,起始和结束控制线都应该处于相同的角度(只是方向相反),当然长度也相同。这一点很重要,因为它很容易出错。曲线上的所有其他点只有一个控制点/线,它指向与曲线绘制方向 *相反* 的方向。该线段越长,曲线在该控制点处就越不“尖锐”,长度为零会产生一个“点”。“
但是,我应该提醒你,“
在这种情况下,弧线不太均匀,你会得到类似于倒置的鲨鱼鳍的东西,而不是帆。请记住,二次弧是抛物线,而椭圆弧基本上生成圆形段。这可能是确定应该使用哪种类型的弧形线段的关键。有关此路径函数的更多示例,请参见 SVG: 二次贝塞尔曲线命令。
请注意,“
“
“
最后,“
这些运算符在 MVG “
翻转图像...
围绕原点旋转 30 度...
对于更复杂的仿射变换,你可以使用为该目的创建的 仿射辅助脚本。这些脚本将诸如旋转角度和中心点之类的内容魔法转换成你可以在“
但是,通过使用 绘制变换,我们可以轻松地为椭圆添加“旋转角度”。
注意,椭圆的“中心”(旋转点)首先被平移,然后才应用旋转。然后在平移位置的“
正在建设中
不仅如此,ImageMagick 还直接理解读取“MVG:” 图像文件格式,允许您更直接地绘制此类命令。但是,除非 MVG 文件定义了画布,否则您可能需要指定初始画布("-size" 和 "-background")以供其绘制。
您可以通过在 MVG 文件中添加“
正在建设中
正在建设中
上面的代码使用“
现在,您生成的绘制字符串可能变得相当长,并且可能会开始导致最终命令长度出现问题。因此,与其将点转换为长字符串,然后将它们传递到命令行的 IM 上,不如将绘制命令作为文件管道传输到 IM 上。这次我还使用 SVG 路径 绘制方法,而不是 绘制图元 绘制方法。此外,我生成的符号是围绕每个点的三角形。
SVG 路径 实际上使这变得更容易,因为它允许相对像素移动,允许您设计符号,使其只需要一个初始的绝对移动“
现在,您可以更进一步,将一个完整的 MVG 文件(包括绘制画布规范)直接馈送到 IM,作为一个绘制命令的管道。这次让我们来绘制一个“十字”,它类似于上面的第一个“加号”示例,它需要大量计算。
这使用了特殊的 shell 编程技巧,其中在 shell 圆括号中“回显”的任何内容都将作为 MVG 文件馈送到最终的“
关于在更大的背景上合成图像的示例,请参阅 图像分层 部分。但是,循环方法可能更有用,例如在 分层图像的编程定位 中给出的方法。将来:使用坐标分层图像的示例
然后可以使用 Alpha 形状算子 将结果直接转换为彩色叠加。这最大的优点是您实际上不需要知道每个符号的具体位置。或者有多少个符号。但这也有可能是缺点。一个主要的缺点是,位置仅位于整数位置。您不能使用浮点“亚像素”定位进行“绘制”。
为了实现这一点,我使用了一个专门的脚本“
这将生成四个文件,例如“
仅应使用小型图像,并且像素点之间应有足够的间隔,以防止符号重叠。这是因为 卷积 会将重叠区域加在一起,使它们比预期更亮。上面的代码已被转换为 UNIX shell 脚本“
这项技术来自 IM 论坛上的一场讨论 IM 的有趣体验。用户希望在足球场的背景图像上放置微型人物,以便他们的位置在图片中拼出某个人的姓名。
Fred Weinhaus 指出,通过使用平移,您可以消除计算圆圈边缘坐标的需要,而只需直接给出半径即可。
但是,在绘制多个圆圈时,上面的方法将需要对每个圆圈进行单独的“
您也可以通过绘制一条非常非常短的带有 '
不幸的是,此技术无法勾勒出生成的圆形,但对于覆盖大区域,较大的笔划宽度可能会有用。请参阅下面 一些简单的示例。此方法使用 SVG 路径 绘制方法,因此可以绘制圆形,而无需计算任何额外的坐标。
仅需要初始绝对移动 '
Fred Weinhaus 添加了以下贝塞尔曲线圆形方法。它非常接近真正的圆形(虽然不完全相同),并且需要浮点数计算。
如果您不关心绘制精确的圆形,可以使用此 4 段贝塞尔曲线 SVG 路径,该路径仅使用圆形的 X 和 Y 边界进行计算。
如果您喜欢一个完全相对于中心起点绘制的圆形,可以使用此技术。仅使用半径值,使其易于生成,仅使用 API 中的字符串函数。
您能想到其他绘制圆形的方法吗?
请注意,我绘制了符号,使其起点是线的末端。这样,它可以向后绘制在先前绘制的线的顶部,从而形成一个非常漂亮整洁的符号。但是,箭头具有关联的方向。您可以创建大量的箭头定义,它们位于许多不同的角度,许多程序都这样做。但由于箭头是一个矢量,所以为什么不将箭头作为矢量旋转呢?IM 绘制命令内置了绘制旋转 (画布扭曲),所以让我们使用它们。这样做也具有将位置从箭头头的 '
如果您想更改箭头的尺寸,请在旋转后添加 "scale" 绘制选项。
请注意,它是如何放大的,将箭头的 '尖端' 放在您指定的位置。这是处理箭头的一个非常重要的方面,因为只有添加箭头的线的端点和角度才重要。'转换' 的顺序很重要,实际上与它们执行的顺序相反。也就是说,首先将缩放应用于坐标,然后旋转,最后平移。如果坐标转换没有按该顺序进行,我们将最终也会缩放箭头的最终位置,而它不会出现在我们预期的位置。另外,由于缩放有两个数字,并且原始箭头头符号是水平设计的(角度为零),您可以分别缩放箭头的宽度与其高度。还要注意笔划宽度如何随箭头头的尺寸而缩放,从而保持一致性。
现在,当您扭曲画布以绘制单个箭头时,也许还有许多其他绘制操作,您可能希望在一个 "
'
或者,您可以生成小丑相当复杂的笑容。
您能想出什么?让我们知道。
通过用渐变阴影替换第一个填充颜色(使用 内存中平铺技术),您可以使圆柱体看起来更像 3D...
通过缓慢地改进圆柱体绘制(如 IM 论坛中所讨论的),您可以走得很远,生成非常复杂且视觉上令人愉悦的圆柱体。这包括添加封闭的半透明玻璃圆柱体、阴影效果和标签。该讨论的最终结果是一个脚本 "
第一张图片来自我使用过的 "
这种使用百分号 '转义'(以及 '
有关 '百分号错误' 的更多详细信息,以及在使用旧版 ImageMagick 中的 "
以及双引号……
但是,如果您使用 '
但是,从文件读取注释字符串时,所有转义将被完全忽略。
有关更多信息,请参阅 注释文本绘制运算符,尤其是 注释转义字符。
完美。产生了正确的对角线渐变。
如您所见,内部 MSVG 转换失败,返回的是垂直渐变而不是对角线渐变。您还可以看到 IM 通过将 SVG 直接转换为 MVG 文件生成的实际 MVG 命令。您可能已经看到 MSVG 转换器如何尝试将 SVG 奇妙地转换为 MVG 绘制命令。当前内部 MSVG 已知无法处理的事情包括……
请注意,我使用 PNG 格式图像来创建上面示例中较大的透明背景版本。这会生成比 GIF 图像格式生成的图像更清晰的图像,因为半透明边缘像素。当最终图像中涉及透明度时,始终建议使用 PNG。
但是,要使此功能正常工作,必须安装 'development' "
当然,这不会从 "
当然,这不是完整的列表。即使是许多文字处理器,例如 OpenOffice、Word 和 TeX,通常也具有各种简单但难以使用的对象编辑器。但是,对于将矢量图形格式转换为不同的矢量格式,请勿使用 ImageMagick。ImageMagick 从本质上讲是一个栅格图像或位图图形转换器和操作器,并且始终如此。有关更多信息,请参见 关于矢量图像格式的说明。
![]() |
|
-draw
" 运算符的其他更通用的方面。绘制命令最初是用来创建简单图像的,但随着时间的推移,它已扩展成为矢量图形到光栅图像转换的接口。ImageMagick 绘图命令
计算机中的图像通常以两种不同的方式保存。您在这些示例页面中看到的第一种也是最常见的方式被称为光栅图形。在这种方法中,图像以矩形像素数组的形式存储。另一种方式不太常见,也不太可修改,但在另一方面更灵活,即对象矢量图形。在这种形式中,图像以线条、弧线、颜色填充以及有时还包括深度来描述。这很有用,因为您可以将这些图像缩放至几乎任何大小,它们仍然可以完美地显示。与光栅格式等效图像相比,您还可以使用非常小的空间来描述非常大而复杂的图像。矢量图形图像的示例包括 Postscript 和新的 SVG - 可缩放矢量图形。True-Type 字体也是矢量图形的示例,因为这使得可以以任何比例使用单个字符描述。图像操作符 "-draw
" 是 ImageMagick 矢量绘制功能的窗口,并形成一套与 IM 的正常命令行图像操作符截然不同的命令。![]() ![]() |
一般而言,只有几种矢量图形文件格式在使用,因为每种格式通常都与其他格式大不相同。结果是代码共享几乎不可能。 因此,ImageMagick 更关注使用矢量图形绘制 SVG 格式的图像。Postscript 和 True-Type 字体图形将传递给其他更适合绘制这些类型矢量图形格式的外部 '委托' 库和应用程序。 也就是说,并非表示没有可用于 SVG 的委托。一个例子是 RSVG 库或 GTK SVG 库,它们在编译时可用。IM 将链接到这些库以对 SVG 进行魔法处理,而不是尝试自己完成。 |
基本绘图命令
让我们从 "-draw
" 图像操作符 MVG 命令中最古老、最简单、最常见的绘图基本图形开始。请注意,所有参数都将被视为浮点数,并且不必是整数,例如我在这些示例中通常使用的数字。 颜色填充基本图形。
|
![]() ![]() ![]() ![]() |
arc
' 绘图基本图形与矩形一起列出,因为它实际上只是适合在由两个坐标定义的 'rectangle
' 内的 'ellipse'。部分弧线很少使用,因为除非角度限制为九十度的倍数,否则很难确定端点。'
circle
' 和 'ellipse
' 基本图形涉及 'center' 坐标,以及 'edge' 坐标或 'size' 和 'angle 值(分别对应)。
|
![]() ![]() ![]() |
|
![]() ![]() ![]() ![]() |
|
![]() ![]() |
-gravity
" 影响的绘制操作。这些操作的其他修饰符包括:"-fill
","-tile
","-origin
","-stroke
","-strokewidth
","-font
","-pointsize
","-box
"。还有一些其他修饰符,但它们与更高级的 Magick 矢量图形语言 相关。 贝塞尔曲线基本图形
'bezier
' 基本图形用于绘制曲线。每个命令仅绘制一个曲线段。通常给出 4 个点(8 个数字):一个起始点 'knot'、两个控制点和一个结束点 'knot'。两个控制点定义曲线偏离连接的结束点 'knot' 的方向和速度。为了使两条曲线平滑连接,结束点的控制点应通过 'knot' 进行镜像,以形成下一条贝塞尔曲线中的控制点。例如,这里我绘制了两条平滑连接在一起的贝塞尔曲线。注意控制线和控制点(也已绘制)如何通过连接坐标直接镜像,角度和长度都相同。这很重要,否则曲线不会平滑。
|
![]() |
|
![]() |
|
![]() |
|
![]() |
bezier
' 基本图形在没有指定所有 4 个点的情况下实际上没有用。只有第一个和最后一个点被归类为 'knots',曲线将通过(或结束)这些点。所有其他中间点被纯粹视为控制点,它们影响所给序列中的曲线,控制点越远,它对曲线该段的影响就越大。
|
![]() |
bezier
' 曲线段使用超过 4 个点或少于 4 个点,以保持简单。实际上,我建议您根本不使用 'bezier
' 基本图形,而是使用 SVG 路径三次贝塞尔曲线 来生成曲线。它有一个特殊的 'S
" 曲线延续函数,该函数会自动进行适当的控制点 'reflection' 以生成平滑连接的曲线段,并减少您需要使用的控制点的数量。您还可以相对于路径的最后一个端点定义点。 颜色填充基本图形
除了上述 'simple' 基本图形之外,"-draw
" 还提供了一组颜色填充或修改基本图形。这些基本图形会根据所选方法修改图像中从指定点开始的颜色。这些填充方法实际上不是真正的 'draw' 命令,而是颜色替换函数。它们被添加到绘制中,因为在该程序的早期版本中,这是在 ImageMagick 中插入它们操作的最简单方法。与上述情况一样,所使用的颜色由 "-fill
" 颜色设置设置,但如果设置,则将使用 "-tile
" 图像。上述其他设置选项不会使用,也不会对这些操作产生任何影响。您还将对这些基本图形应用两个额外的设置,"-bordercolor
" 和 "-fuzz
" 因子设置。但是,这些设置不能在 'MVG' 语言中定义,因此只能在使用 "-draw
" 操作符之前设置。您已经看到第一个 'color point
' 作为上述示例中 'point
' 绘图基本图形的替代方案。如果您仔细观察,您将看到我们在测试图像中设置的单个白色像素。
|
![]() |
point
' 函数用半透明蓝色绘制覆盖红色像素,从而得到紫色结果。但是,如果使用 'color point
' 函数(最后一个或最右边的像素),则红色将被半透明蓝色像素完全替换。它不会被叠加。
|
![]() |
color
' 函数都执行完整颜色替换,而所有其他颜色基本图形都会在图像顶部 'paint' 颜色。因此,您可以使用 'color
' 来绘制透明颜色。'color replace
' 绘图函数将替换在指定位置处所有完全匹配给定颜色的实例。正如您所见,这些区域不必连接。
|
![]() ![]() ![]() |
-opaque
”图像运算符。此函数还使用“-fuzz
”因子设置来增加与给定颜色匹配的颜色范围。'floodfill
' 方法也非常简单,因为它只会填充所选点周围的整个区域,而不会选择任何其他以某种方式未连接的类似颜色的区域。您还可以使用“-fuzz
”来扩展填充的区域,以包含类似的颜色。在本例中,我们选择了一个足够高的值,也包括跨越边界,允许洪水填充“泄漏”到图像的另一侧。
|
![]() ![]() ![]() |
filltoborder
' 与 'floodfill
' 类似,只是您指定一个颜色作为要填充区域的边界,而不是由填充过程替换的颜色。当然,也建议使用 模糊因子 将“相似颜色”包含在该边界颜色选择中,以进一步限制洪水填充。
|
![]() ![]() ![]() |
reset
”,它只是将整个图像替换或重置为填充颜色。在这种情况下,实际选择的像素对结果没有任何影响。
|
![]() |
-tile
”图案来填充区域。 Alpha 填充基本图形
“alpha
”绘制原语的工作方式与上面描述的“color
”原语完全相同,除了它不会替换所选区域的颜色,只会替换所选区域的“alpha”通道。(也就是说,只有“alpha”通道受到这些填充函数的调整)。就像“color
”填充函数一样,“alpha”值使用填充颜色(除非“-tile
”作为要使用的“alpha”值的来源)。在这里,我们使用上面相同的“color floodfill
”示例,但这里只调整 alpha 通道以使填充部分完全透明。也就是说,原始颜色仍然存在,只是透明!
|
![]() ![]() ![]() |
alpha reset
”函数也可以用来使整个图像半透明。当然,在这种情况下,我们必须输出到 PNG,因为它可以接受图像中的半透明颜色。
|
![]() |
black
”颜色组件未在操作中使用,仅使用颜色的 alpha 组件。图像的原始颜色保持原样。未来:使用“-tile
”图案进行有趣的 alpha 效果。“color
”和“alpha
”都是完整的颜色替换函数,它们总是产生布尔(全有或全无)类型的颜色替换。因此,这些区域的边缘总是会显示 锯齿效果。因此,它们通常不是通用图像开发的良好图像运算符,除了设置 GIF 图像的透明区域(它们也是布尔值)。然而,并非一切都已丢失,正如 背景去除 的示例中所见。绘制命令的详细信息
像素坐标
“-draw
”命令(以及 IM 中的许多其他命令)使用它称为“像素坐标”。也就是说,“10,10
”的坐标是从左上角开始向下向左 10 像素的像素中心。在此坐标系中,0,0 是左上角像素的中心,而 w-1,h-1 是右下角像素的中心。实际边缘位于 -0.5,-0.5 和 w-0.5,h-0.5,而中心像素(如果图像尺寸为奇数)位于 '(w-1)/2,(h-1)/2
'。但是,当您以数学方式处理图像时(例如,当使用扭曲时),实际像素没有实际意义,因此它使用“图像坐标”。在此系统中,图像的实际边缘位于 '0,0
' 和 'w,h
'。而图像的中心(可能或可能不是像素的中心)位于 'w/2,h/2
'。为了将“像素坐标”转换为图像坐标,请添加 ½ 因此,左上角像素的中心是 '0.5,0.5
',而右下角像素是 'w-0.5,h-0.5
'。示例:小图像中圆的中心 使用伽玛和色彩空间校正进行绘图
与几乎所有 ImageMagick 操作一样,“-draw
”是一个线性运算符。因此,它在线性 RGB 色彩空间中工作。这意味着为了获得平滑的边缘,您可能需要在保存图像之前对其进行一些 gamma 校正,以便它们使用非线性(gamma 校正)sRGB 色彩空间存储。例如,如果您绘制一个大圆圈,然后直接保存它...
|
![]() |
要解决此问题,我们需要在保存图像之前向图像添加 gamma 校正。
|
![]() |
|
![]() |
![]() ![]() |
请注意,sRGB 色彩空间(这是保存图像的正确方法)与简单地应用 2.2 gamma 校正并不完全相同。但是,两者之间的结果差异很小,并且仅在非常暗的图像中可见。 |
![]() ![]() |
在 IM v6.7.5-1 之前,色彩空间名称“sRGB”和“RGB”(线性 RGB)实际上是相反的。因此,在旧版本的 IM 上,上述两个标签应互换。 |
|
![]() |
|
![]() |
|
![]() |
![]() ![]() |
上面绘制的线条使用“-stroke ”颜色。您可以使用“-fill ”绘制线条并获得相同的结果,但您将无法使用“-strokewidth ”控制线条粗细。有关更多信息,请参阅以下 笔触颜色设置。 |
![]() ![]() |
颜色名称实际上是使用“sRGB”色彩空间的值定义的,但绘制时却认为图像在线性 RGB 色彩空间中。因此,使用上述 gamma 校正和命名颜色(除“白色”或“黑色”以外的颜色)会导致这些颜色发生失真。在这种情况下,最好不要使用 gamma 或色彩空间校正,以便命名颜色可以正确映射。 将命名的“sRGB”颜色正确映射到正在绘制到的图像的色彩空间,将作为 IMv7 开发的一部分进行修复。 |
笔触、笔触宽度和填充交互
当在字体的边缘周围绘制轮廓时,将使用“-stroke
”和“-strokewidth
”选项。这些选项通常与“-fill
”一起使用,可以使文本更加有趣,而且操作非常简单。
magick -size 380x70 xc:lightblue -pointsize 50 -font Chisel \ -fill green -stroke black -draw 'text 10,55 "Black Border"' \ stroke_font.jpg |
![[IM Output]](stroke_font.jpg)
-strokewidth 1
”和“-stroke None
”。但这使得轮廓笔触不可见,只留下了“-fill
”颜色,您将看不到它。“-strokewidth
”在“-stroke
”为“不可见”时唯一的效应是在字体大小属性上,这意味着它仍然可以影响字体定位和 标签和标题 图像生成的尺寸。否则,宽度将没有可见效果,直到您使笔触可见为止。要查看“-strokewidth
”实际上是如何影响字体的外观的(当可见时),在这里我绘制了一些具有各种宽度的文本,从“关闭”到越来越大。
magick -size 320x420 xc:lightblue -pointsize 70 -font Vademecum \ -fill red -stroke none -draw 'text 30,80 "Stroke -"' \ -fill red -stroke black -strokewidth 0 -draw 'text 30,160 "Stroke 0"' \ -fill red -stroke black -strokewidth 1 -draw 'text 30,240 "Stroke 1"' \ -fill red -stroke black -strokewidth 2 -draw 'text 30,320 "Stroke 2"' \ -fill red -stroke black -strokewidth 3 -draw 'text 30,400 "Stroke 3"' \ stroke_table.jpg |
![[IM Output]](stroke_table.jpg)
-strokewidth
”设置为“0
”与将“-stroke
”颜色设置为“none
”(默认值)不同。前者产生一个非常非常细的笔触轮廓,而后者实际上将其关闭。在这两种情况下,笔触仍然被绘制。但是您还应该注意,即使使用“-strokewidth
”为“0
”,图像轮廓也将比仅使用纯“填充”图像(使用“-stroke
”颜色为“none
')稍微扩展一点。本质上,使用任何小于“1.0
”的宽度都不起作用。在这些情况可能重要的场合,您应该谨慎行事。但是请记住,“-strokewidth
”也是一个浮点设置。也就是说,“0.5
”的笔触宽度也是有效的。但是,这通常只在您试图使用 绘制细的位图圆圈 时 抗锯齿 被关闭时才很重要。以下是如何使用非常大的笔触宽度的示例。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 -fill white \ -stroke black -strokewidth 15 -draw "text 25,65 'Anthony'" \ stroke_thick.jpg |
![[IM Output]](stroke_thick.jpg)
-strokewidth
”会向内和向外扩展线条。以下是用相同示例重新绘制的字体,但没有笔触轮廓,从而去除了非常粗的笔触的内部部分。
magick -size 320x100 xc:lightblue -font Candice -pointsize 72 -fill white \ -stroke black -strokewidth 15 -draw "text 25,65 'Anthony'" \ -stroke none -draw "text 25,65 'Anthony'" \ stroke_outline.jpg |
![[IM Output]](stroke_outline.jpg)
绘制(笔触)线条
IM 中的默认线条绘制有一些奇怪的行为,值得了解。以下是默认的线条绘制...
|
![]() |
-fill
”选项设置线条的颜色。
|
![]() |
-stroke
”颜色来使线条稍微粗一点。
|
![]() |
-fill
" 选项指定的白色颜色发生了什么? 这是 ImageMagick 中绘制线条的棘手之处。该程序实际上将线条视为一个大约 1 像素宽的填充对象。这很自然,因为通常使用多条线来扫过要填充的区域。因此,就像我们在上一节中使用字体进行描边一样,IM 使用填充颜色绘制线条(或对象),然后使用描边颜色在其周围绘制。结果是上面的描边颜色线条现在稍微厚一点,填充颜色完全隐藏在下面。如果将描边颜色设置为半透明,就可以再次看到填充颜色。总而言之,线条似乎是用 "-fill
" 颜色绘制的,但一旦 "-stroke
" 颜色被定义为除默认的 "none
" 或 "transparent
" 颜色之外的其他颜色,该选项就毫无意义了。![]() ![]() |
选项 "-linewidth " 实际上只是 "-strokewidth " 的别名,不应使用。 |
-stroke
" 颜色是不可见的,因此您无法看到它。您只能看到线条一像素宽区域的内部“填充”。
|
![]() |
![]() ![]() |
我实际上认为上述结果是一个错误。不应该绘制任何内容,因为没有要填充的“区域”,并且没有设置线条“描边颜色”。IM 当前这样做的原因是为了避免与新用户混淆,但实际上它只是给高级用户带来了问题。有关详细信息,请参见 绘制填充边界。 |
|
![]() |
-strokewidth
" 设置设置为 1,则上面的线条将被完全覆盖。
|
![]() |
|
![]() |
-strokewidth
" 设置 '0
',就像我在上面对字体所做的那样。
|
![]() |
|
![]() |
![]() ![]() |
“颜色拍频”效应与当您有两把吉他稍微失调时产生的“声音拍频”类似。在这种情况下,您会在描边颜色完全覆盖底层填充颜色时得到一个黑点,而您会在描边颜色与填充颜色和背景颜色混合时得到一个灰点。
颜色混合是 IM 使用的反锯齿过程的自然结果,这些过程试图改善线条和其他绘制对象的视觉效果。有关更多信息,请参见我的 IM 中的反锯齿 讨论和示例页面。 |
|
![]() |
|
![]() |
|
|
![]() |
|
|
![]() |
|
让我们将其与无描边的描边进行比较...
|
![]() |
![]() ![]() |
这些结果不仅是由有问题的描边宽度 0 导致的拍频,而且还与“填充颜色”以额外的 1.0 直径厚度绘制有关,而实际上没有要填充的区域。我也认为这是一个错误。请参见 绘制填充边界。 |
绘制填充边界
您应该注意各种绘制原语的几个其他要点。描边宽度对于大于 1.0 的浮点值效果很好,但对于小于 1.0 的值似乎会失效。这是由于所用实现算法造成的,而不是因为它本身有错误,因为它对较厚的线条效果很好。基本上,如果您使用 0 的描边宽度,您可能会期望不会添加描边颜色。相反,您将得到一种拍频模式,其中描边颜色在线条穿过像素的实际“中心”时强度最大。实际上应该发生的是,添加到像素的颜色量应该反映所绘制线条的面积,而不是像素到该线条的距离。因此,宽度为零的线条不应向图像添加任何颜色,而厚度小于 1.0 的线条只应添加更少的颜色。请参见上面的示例 绘制线条,带描边宽度和描边。另一个问题是,填充颜色没有应用到所绘制形状(多边形)的边缘,而是向外扩展了 ½ 像素。这包括没有应用“描边”的情况,边缘应该准确。它还包括绘制“线条”,实际上它具有“零”填充厚度。基本上,如果您绘制一条线条,而没有启用描边,从技术上讲,您应该看不到任何线条,因为它没有“填充”厚度。相反,线条正在绘制,至少包含 1 像素宽的“填充”颜色。这是出于历史原因,通常避免新用户对 IM 感到困惑。不幸的是,这对高级用户来说是不正确的。这意味着,如果您使用仅填充颜色绘制两个共享一个边缘的多边形,该边缘将重叠 1 个像素,因为每个多边形在其所有边缘上都比请求的尺寸大 ½ 像素。换句话说,多边形和其他形状不匹配,而是重叠!例如,这里我尝试使用绘制将图像分成两半(在白色上绘制黑色)。为此,我绘制了两个共享一个边缘的多边形,完全没有重叠。生成的“微小”图像已放大以供显示。
magick -size 10x10 xc: -draw 'polygon 2,-1 7,10 10,10 10,-1' bound_left.gif magick -size 10x10 xc: -draw 'polygon 2,-1 7,10 -1,10 -1,-1' bound_right.gif magick bound_left.gif bound_right.gif -compose Plus -composite bound_add.gif |
![[IM Output]](bound_left_mag.gif)

![[IM Output]](bound_right_mag.gif)

![[IM Output]](bound_add_mag.gif)
-strokewidth 1.0
" 设置。因此,通常情况下,预计这个额外的区域将被正常的描边宽度覆盖。但是,这会导致一些真正的问题。旁注:要对连接进行完整测试,您将生成黑色背景上的 50% 灰色区域,并将它们加在一起。这样,您就可以查看区域不仅“重叠”(如上所示),而且在将区域加在一起时还会测试它们是否“不重叠”(在填充区域之间留有间隙)。生成的图像应该是完美的平滑 50% 灰色,连接处没有颜色变化。透明度检查将涉及,在完全透明的背景上使用 50% 透明的 50% 灰色。要查看基于单个蒙版图像的完美剪切和重新添加的示例,请参见合成方法示例 合成 DstOut。未来错误修复:填充区域应该是准确的,但是为了弥补这一点,在绘制形状时,默认的“描边颜色”应设置为填充颜色(除非它本身被专门设置)。MVG - Magick 矢量图形
上面显示的原语构成了所有 "-draw
" 操作的基础。它们一起是 ImageMagick 中名为 Magick 矢量图形 语言的特殊内部语言的起点。有关此语言的更多详细信息,请参见 IM 网站上的 MVG 原语和语法的摘要。这种“MVG”语言的目的是让 ImageMagick 能够处理更复杂的 SVG (可缩放矢量图形) 语言。它通过尝试将给定 SVG 格式的图像转换为更简单的内部 MVG 格式来实现这一点。有关更多详细信息,请参见下面的 SVG 处理。因此,您上面看到的只是 "-draw
" 运算符功能的一小部分。但是,如果您要绘制复杂的对象,我建议您使用 SVG 编辑器(例如 "Sodipodi
")创建一个单独的 SVG 格式的对象图像。(请参见下面的 非 IM 矢量图形程序)。与 SVG 不同的是,MVG 没有任何形式的“容器”或图像命令集。这些都在转换过程中被删除,以产生简化的 MVG 绘制命令序列。相反,它使用 图形上下文 的概念来保存和恢复各种绘图设置,这就是我们现在要看的。 命令行设置与 MVG 设置
首先,几乎所有通过命令行选项设置的设置,这些设置被绘制原语使用,在 MVG 绘制命令中都有直接的等效项。通过命令行选项设置(例如 "-strokewidth")与在 MVG 绘制字符串中使用设置(例如 'stroke-width
')之间的主要区别在于,MVG 设置仅在 MVG 命令字符串的持续时间内有效。Summary of the General Drawing Settings __cmd_option__ __draw_MVG__ __Argument__ -fill fill color/tile for inside shapes -tile fill image tile, replaces fill color -stroke stroke line color/tile around the shapes -strokewidth stroke-width pixel width +antialias stroke-antialias 0/1 aliasing line edges -font font font_name / font_file -family font-family ? -weight ? ? -stretch ? ? -pointsize font-size height in points -kerning - extra inter-character spacing +antialias text-antialias 0/1 aliasing drawing text -box text-undercolor fill color for font bounding box - decorate (None, Underline, LineThrough or Overline) -gravity gravity (None, North, South-East,...) -fuzz - color delta / percentage -bordercolor - color Notes: - no such option ? unknown这些设置通常很容易理解,因为它们经常被使用,并且在上面有演示。
![]() ![]() |
字体、拉伸、样式和粗细用于从 ImageMagick 字体列表中识别字体。但是,大多数人只是选择特定的字体和字号来使用。因此,它们很少在 IM 中使用。 |
-draw
" 运算符之前从命令行指定。一些 MVG 设置可能更适合作为全局命令行设置,例如用于字体绘制的 'decorate
' 设置。警告:"-gravity" 不是 SVG 规范的一部分。在 MVG 中,它仅用于文本和图像的放置以及对齐。目前没有与默认的“重力”效果分离的对齐设置。但是,由于对齐是 SVG 文本处理的一部分,这可能会在将来发生变化。现在,全局命令行设置(在 MVG 绘制字符串之外)用于初始化您应用的每个 "-draw" 操作的设置,这就是为什么您可以设置 "-fill" 颜色,然后用它来绘制该颜色的圆形。
|
![]() |
|
![]() |
|
![]() |
|
![]() |
MVG 特定设置
即使使用基本操作,控制线条和对象绘制方式的其他 MVG 设置也很有用。这些包括..__draw_MVG__ __Description/Argument__ fill-opacity fill transparency, from 0.0 to 1.0 clip-rule fill style for crossed lines (evenodd, nonzero) stroke-opacity line transparency, number from 0.0 to 1.0 stroke-dasharray list of 'on' and 'off' lengths for lines stroke-dash stroke-linecap End of line look: butt round square stroke-linejoin Lines joins: butt miter round square stroke-miterlimit Angle when 'miter' joins become 'bevel' (or 'butt')请记住,可以在 IM 网站的 MVG 基本图形和语法摘要 中查看所有 MVG 设置和绘制运算符的完整列表。让我们看一下一些更简单的设置的效果…
|
![]() |
|
![]() |
||
|
![]() |
|
![]() |
||
|
![]() |
|
![]() |
||
![]() |
stroke-miterlimit
' 设置很难演示。此属性定义将 'miter
' 连接改为 'bevel
' 连接的角度。基本上,对于非常锐利的角度,斜接可以从两条线的实际连接处延伸很长一段距离。这为这种锐度设置了最大限制,并在斜接变得太长时将角点钝化。但是请注意,它代表某种角度的三角函数值,而不是长度或距离。该值必须大于 1.0。上面显示了如何将斜接突然神奇地转换为斜角,在 6 到 7 之间的值之间。例如,'stroke-miterlimit
' 为 1.414 将 'miter
' 转换为 'bevel
',用于任何小于 90 度的角度。值为 4.0(默认值)将连接转换为小于大约 29 度的角度。而值为 10.0 将它们转换为小于大约 11.5 度的角度。 SVG 路径绘制
SVG 路径是 SVG 的基本绘制基本图形。它用于绘制线条、形状、圆形、曲线、弧线等等。可以在 SVG 路径规范 文档中找到 SVG 路径的完整规范。但是,这并不是一份容易阅读的文档,因为它实际上是为程序员而不是用户准备的,因此我将简化和总结路径规范…- 字母是命令,而所有数字(浮点数)都是参数。
- 逗号或空格可以用作参数分隔符,否则将完全忽略。
- 每个路径组件的最后两个参数 (x,y) 将成为该路径组件的终点(或“节点”)。
- 大写字母指定最终点的绝对坐标。
小写字母相对于前一个组件的终点。
例如:“M 1,2 l 3,4 l 2,-4
”与“M 1,2 L 4,6 L 6,2
”相同。
也就是说,将 3,4 添加到 1,2 中,以绘制一条到 4,6 的线。
然后将 2,-4 添加到以绘制一条到最终坐标 6,2 的线。 - 每个元素的参数可以通过添加更多数字参数组来重复,而无需重新发布相同的路径字母。但是对于曲线,我建议您无论如何添加函数字母,以便于阅读。
- 重复的“
M
”或“m
”参数分别被视为“L
”或“l
”。
例如:“M 1,2 3,4 5,6
”与“M 1,2 L 3,4 L 5,6
”相同
以及:“m 1,2 3,4 2,-4
”与“m 1,2 l 3,4 l 2,-4
”相同 - 对于三次贝塞尔曲线,所有点(控制点和终节点)都是相对于前一个路径组件的终点给出的。
|
![]() ![]() ![]() |
Z
' 仅闭合循环。它不会创建单独的对象。因此,两个“闭合”路径仍被归类为单个绘制对象,无论它们是重叠还是完全断开连接。 在这里,我们显示了两个闭合但重叠的循环,它们以相同的方向绘制。由于仅使用单个路径,因此该对象是一个单一对象,并且“fill-rule
”设置控制如何填充重叠区域。
|
![]() ![]() |
evenodd
' 规则使该区域未填充,而非零 'nonzero
' 规则则填充了它。但是请注意,所有路径都是可见的,因为它们实际上是同一个对象。路径绘制的方向非常重要,通常所有路径应该相对于对象的“内部”以完全相同的方向绘制。例如,这里我以与第一个对象相反的方向绘制第二个对象。因此,当两个对象重叠时,该区域将被“零”次环绕。也就是说,无论使用什么“fill-rule
”,它都将未填充,从而创建一个“孔”。
|
![]() ![]() |
|
![]() |
fill-rule
”设置如何,结果都是一样的,因为孔既是“偶数”又是“零”,因此未填充。当然,如果您使用完全独立的“path
”元素,您将生成一个完全独立的对象。在这种情况下,“fill-rule
”不适用,并且对象只是按给定的顺序彼此叠加绘制。
|
![]() |
FUTURE: coordinate aligned paths "H" and "V"椭圆弧线是 SVG 路径的圆形绘制函数…
“large”和“sweep”参数尤为重要,因为它们用于确定将以四种方式中的哪一种从起点弧形到该路径组件的终点。
两个标志“large”和“sweep”定义了该半径的四个弧线中的哪一个将连接这两个点。
|
![]() ![]() ![]() ![]() |
|
![]() ![]() ![]() |
|
![]() |
1,1
”的长度会导致完美的半圆,从一个点到另一个点。在这种情况下,椭圆角度将没有区别。
|
![]() |
|
![]() |
0,0
”的弧线都只是一条简单的直线弧线…
|
![]() |
|
![]() |
|
![]() |
|
![]() |
L
' 被一个弧线段替换了。但是,弧线的大小应该与线的长度成比例。由于我没有这样做,因此较长的对角线具有比其他两条线更强、更深的曲线。请记住,在调整大小或缩放要绘制的对象时,您也应该按与该线长度相同的比例缩放半径,以便曲线也按比例缩放,因此弧线也按比例缩放。请注意,“sweep”标志控制曲线根据每个路径段绘制的方向向外凸出还是向内凹入(见上文)。
|
![]() |
|
![]() |
C
”函数来定义。对于使用最后一个控制点的镜像(用于连续曲线)的连续三次贝塞尔曲线,可以使用“S
”函数。以下是一个示例。由于此函数的复杂性,我已经预先准备了一个画布,显示了控制点的位置以及最后一个控制点的“假想镜像”。
|
![]() |
|
![]() |
S
”函数在内部从上一段的数据中为下一段生成镜像控制点/线,从而产生曲线的平滑延续。有关此路径函数的更多示例,请参见 SVG: 立方贝塞尔曲线命令。手动生成贝塞尔曲线 比较简单,无需任何花哨的 GUI 工具。- 首先定义你想让你的曲线经过的所有坐标点,在列表末尾重复起始坐标。
- 现在通过将所有 x,y 坐标点加倍成对来扩展此列表,并在每对之前添加一个“
S
”(平滑三次)函数。每对中的第一个数字是连接到代表曲线上的点的第二个数字的控制点。然而,第一个点对对此进行了逆转,第一个点是曲线的起点,第二个点代表第一个也是唯一一个反转的控制点。 - 将第一对坐标的函数字母从“
S
”更改为“M
”,然后在这对坐标之间添加一个“C
”。最后,从第二对坐标中删除“S
”,以完成初始三次(“C
”)函数。 - 通过添加一个最终的“
Z
”来关闭曲线,从而完成路径。
请参见上面的示例序列,了解它应该是什么样子。 - 此时,你可以测试绘制你的路径。路径将仅包含直线段,因为所有控制线的长度都将为零。
- 你现在需要做的就是缓慢而仔细地调整控制线段的位置(每对“
S
”的第一个坐标),以获得你想要的最终曲线。不要让控制线过长,或者方向错误,否则你会得到一个非常奇怪的曲线。 - 为了帮助你查看更改并找出错误,使用上面的转换“
sed
”命令在路径控制点和曲线控制点之间绘制控制线。但是请注意,零长度控制线是不可见的,但由于 lin 将产生一个尖点,因此位置应该是显而易见的。 - 最后,确保在“
C
”之后的第一个控制点/线与结束控制点/线完全相反,并且位于相同位置。
你知道其他方法来提取贝塞尔曲线(每个曲线上的点给出两个或一个控制点)吗?使用 GUI 工具。或者,也许还有其他技术来生成此类曲线?给我发邮件!我很想听听你的想法。你将获得与其他人相同的技术荣誉。二次贝塞尔曲线 是三次贝塞尔曲线函数的简化版本,其中两个控制点合并成一个控制点。同样,你可以使用“
Q
”函数开始曲线,然后使用“T
”函数继续曲线,镜像最后一个控制点。
|
![]() |
T
”继续函数实际上只适用于连接等距点的路径。我不建议使用它。二次曲线的优点是可以替代 椭圆弧,因为它使用实际位置而不是半径来表示弧线。它还可以使弧线偏向一端而不是另一端,这在使用 椭圆弧 时不实用。
|
![]() |
绘制表面的变形
除了这些功能之外,绘制对象的绘制表面还可以通过多种方式进行变形,从而允许你做一些令人惊叹的事情。首先,你可以应用一些通用的绘制表面修改,例如...“translate
”、“rotate
”、“scale
”、“skewX
”、“skewY
”和“affine
”。例如,给定一条线的“路径”,我们可以将绘制表面的原点或 0,0 点“平移”到另一个位置。
|
![]() |
0,0
”或绘制区域的原点现在位于图像的中心,尽管 Y 轴在图像的顶部仍然为负,在图像的底部仍然为正。 “rotate
”操作将旋转绘制表面,因此之后绘制在该表面上的任何内容都将以旋转方式绘制。当然,它将围绕平移后的原点旋转,因此最好将这两个变换运算符一起使用。
|
![]() |
scale
”将在原点周围放大和缩小绘制表面。
|
![]() |
scale
”的一种常见用途是翻转 Y 轴,以便正 Y 值向上。当然,还应该将原点移动到中心或左下角,以保持顺序。
|
![]() |
skewX
”和“skewY
”将在 X 和 Y 方向上对图像进行剪切。例如,这里我们使用“skewX
”来使图像的垂直 Y 轴倾斜。
|
![]() |
-draw
”字符串之外具有等效项,用于一般用途。但是,这些命令行版本是运算符,它们立即应用于内存中已经存在的图像,而不是仅应用于尚未绘制的矢量对象的绘制表面。有关更多详细信息,请参见 扭曲图像。绘制表面的仿射变形
以上五个画布变换都可以组合成一个通用的仿射矩阵运算符。可以通过使用 MVG 原语“affine
”或在调用“-draw
”之前使用“-affine
”来设置仿射变换。仿射变换使用一组“*矩阵系数*”,它定义了你给出的坐标如何被修改成实际的绘制坐标。有关这些“系数”的实际工作原理的更多详细信息,请参见 仿射矩阵变换。例如... 仅设置相对于绘制对象的中心原点...
|
![]() |
|
![]() |
|
![]() |
-draw affine
”或“-affine
”设置中直接使用的仿射坐标。 推送/弹出上下文
一些 MVG 图元实际上依赖于这些变换的正确使用。例如,椭圆图元 只能直接指定与正交对齐的轴。
|
![]() |
|
![]() |
0,0
”处绘制“ellipse
”。上面的示例还展示了两个新的 MVG 绘制图元。“push graphic-context
” 和“pop graphic-context
”。在上面的例子中,这些严格来说并不需要,但在进行主要绘制变换时建议使用它们。“push
” 和“pop
” 图元的作用是保存当前绘制状态或“图形上下文”,然后在之后恢复它。这两个图元之间更改的任何绘制设置都会被遗忘。其中包括表面扭曲,例如“translate
” 和“rotate
”,以及颜色设置“fill
” 和“stroke
”,或任何修改绘制“状态”的其他设置。这些图元可以轻松地绘制具有许多变换的非常复杂的物体,然后将事物恢复到更“正常”的状态以进行后续的绘制操作。您可以在下面 绘制箭头 中看到更实用的演示。 推入/弹出特殊对象


More settings used specifically for MVG handling of SVG format. font-family font-stretch font-style font-weight encoding 'UTF-8' push defs push gradient 'def_name' linear X1,Y1 X2,Y2 stop-color 'color' where stop-color 'color' where # where is a point between the two pixels given (0 = X1,Y1 1= X2,Y2) gradient-units 'objectBoundingBox|userSpaceOnUse' affine .... pop gradient push gradient 'def_name' radial CX,CY FX,FY R # Here CX,CY is the center of the radial gradient of radius R # the FX,FY is the focal, and is usually the same a CX,CY # unless you are trying to warp the gradient in a specific direction stop-color 'color' where ... pop gradient pop defs push graphic-context fill 'url(#def_name)' ... draw things here ... pop graphic-context For examples see Florent Monnier's development site... http://www.linux-nantes.fr.eu.org/~fmonnier/OCaml/MVG/
读取 MVG 文件
如您在上面的示例中所见,MVG 的 "-draw" 参数可能会变得很长。实际上,将 SVG 转换为 MVG 会生成一些非常长的 MVG 绘制参数(见下文)。但是,IM 的通用命令行界面允许您通过使用“@filename
” 参数而不是直接传递参数来从文件中读取任何字符串参数。这很方便,因为这意味着您可以从单独的文件中读取非常长且复杂的 MVG 绘制命令。例如,如果我把 MVG 操作放到名为“draw_circles.mvg
” 的文件中,我就可以像这样绘制它…
|
||
![]() |
![]() ![]() |
|
||
![]() |
![]() ![]() |
viewbox
” 并使用相应的背景颜色填充绘制来将初始画布设置移入 MVG 图像。这将 MVG 图像文件作为完整的图像定义完成。
|
||
![]() |
![]() ![]() |
![]() ![]() |
目前只有一种方法可以从 MVG 参数字符串内部读取外部 MVG 文件,那就是使用“image ” 绘制图元。不幸的是,这会将 MVG 包含转换为光栅图像,然后才将该图像叠加到绘制表面上。换句话说,目前没有 MVG“包含”函数。 :-( |


You can generate the low level draw operations of IM, using the "+render
" to record them. When you then give a "-render
" setting/operator, IM will immediately draw those saved operations. Strangely just outputting to a "MVG" file also seems to do this... magick ... -draw '....' draw_commands.mvg NOTE: if you draw a curve while outputting a MVG format file, the file lists the curve as a series of short line segments, rather than the original curve. You can of course go the whole way and use the more universal SVG format. See "SVG format handling" below.
MVG Alpha 合成


I have not seen any use of Alpha composition (other than 'painters' algorithm which is basically a 'over' alpha composition) for the drawing of objects. However that is not to say it can not be done. If you like to compose your rectangle, ellipse, circle, or whatever with a different alpha composition (such as 'DstOver' which is an Under-like composition), then draw your figure on a blank transparent canvas the same size as the original and compose it onto your image. However as SVG allows you to use alpha composition to draw text and other items onto images, I would imagine that it will be a future addition. Stay Tuned!
绘制符号
有时您会在图像上的一组点上绘制参考符号,例如十字架、圆圈等… 不幸的是,目前 IM 没有命令可以轻松绘制此类符号,但通过一些额外的操作,您可以绘制此类符号。符号绘制技巧
在给定的一组位置绘制多个符号的技巧是使用 shell 脚本或您正在使用的任何 API 生成 MVG 绘制命令,以便将给定的点集转换为适当的绘制命令集。例如,这里我将一行点变成了这些点上的“加号”...
|
![]() |
tr
” 将每个点(两个数字)分离到每行一个点,然后使用“awk
” 执行绘制给定点上的“加号”所需的所有数学计算。您可以使用任何您喜欢的工具,因为我仅仅是在输入点列表上应用一种文本宏扩展形式。几乎任何编程语言都可以做到这一点。对于上面的 shell 脚本情况,我发现“awk
” 是最简单和最快的工具。实际上,您甚至可以使用 ImageMagick 本身来执行“宏”扩展,使用“magick
” 格式选项... 例如,这里我使用它来计算圆周上的一个点,作为这个“点符号”。
|
![]() |
|
![]() |
M
”,然后给出绘制符号的“移动”和“线”序列。因此,您实际上不需要任何浮点计算,因为 IM 绘制会执行所需的定位数学运算。![]() ![]() |
相对移动的 SVG 路径 项目“m ” 在 IM v6.4.3-5 之前被破坏了。如果您的 IM 版本早于此版本,上面的(以及接下来的)示例可能无法绘制任何内容。您可以通过将上面代码中的相对移动“m ” 替换为适当的相对线序列“l ” 来修复旧版本。 |
|
![]() |
magick
” 命令中。第一个“回显”定义并填充图像的绘制画布,而“while” 循环将每个“点”转换为给定半径的圆。这种方法的优势在于,您不会遇到使用其他两种方法时可能会遇到的字符串限制。您可以生成的其它符号包括方框、菱形、误差线等… 另外请参阅下面的 绘制圆圈,了解其他圆圈方法,包括无计算的相对“路径”圆圈绘制。 绘制符号的替代方案
除了直接绘制之外,还有其他方法可以在图像中添加符号。符号字体
您可以从 符号字体 中提取符号并将它们保存为一个小的位图。您也可以使用这种方法来使用预定义的但有颜色的图像。但是,这可能会在将字体精确地定位到特定的像素方面遇到问题。也就是说,这不是一种非常精确的技术。但是,您可以将任何图像组合在任何像素位置。例如,这些符号是从许多字体中提取的,用于这些示例页面的特定用途。


















形态学
另一种选择是使用 形态学,使用特殊的“形状”内核(例如“磁盘
” 和“环
” 和“加号
”,甚至您自己的 用户定义内核)对单个像素进行“膨胀”。例如…
magick -size 80x80 xc:black -fill white \ -draw 'point 20,15 point 55,30 point 40,60' points_pixels.gif magick points_pixels.gif -morphology Dilate Ring points_rings.gif magick points_pixels.gif -morphology Dilate Plus:4 points_pluses.gif magick points_pixels.gif -morphology Dilate Cross:3 points_crosses.gif |
![[IM Output]](points_pixels.gif)

![[IM Output]](points_rings.gif)
![[IM Output]](points_pluses.gif)
![[IM Output]](points_crosses.gif)
卷积
几乎相同的技术是使用“卷积”,使用专门设计的内核,这允许您设置各种灰度,而不是像上面那样仅仅是简单的开/关结果。通过对图像的每个通道(红色、绿色、蓝色和 alpha)使用不同的 用户定义内核,甚至可以从每个像素坐标创建多色符号。![[IM 输出]](../images/marker.png)
image2kernel
”,我编写了它来将彩色图像(见右图)转换为每个通道的单独浮点卷积内核。
|
marker_R.dat
”,每个文件对应于非常小的输入图像的每个通道,它们是图像(以图像中心为原点)的 用户定义 表示。现在,使用这些内核数据文件,我们可以对这些单点进行 卷积,以将它们转换为透明背景上的彩色标记图像。
magick points_pixels.gif -alpha off \ \( -clone 0 -morphology Convolve @marker_R.dat \) \ \( -clone 0 -morphology Convolve @marker_G.dat \) \ \( -clone 0 -morphology Convolve @marker_B.dat \) \ \( -clone 0 -morphology Convolve @marker_A.dat \) \ -delete 0 -channel RGBA -combine point_markers.png |
![[IM Output]](points_pixels.gif)

![[IM Output]](point_markers.png)
![]() ![]() |
在 IM v6.7.6-9 之前,组合算子 要求图像的透明度通道以“不透明度”值而不是 alpha 值给出,因此需要对创建的 alpha 通道进行取反。例如
|
convolve_image
”,以便于使用。
convolve_image points_pixels.gif marker.png point_markers.png |
分层
另一种技术,例如 图像分层,可以使用从源图像中提取的像素列表进行定位,这可能是一种更好的方法。您可以先叠加更远的符号图像,然后再叠加前景图像,并且您可以通过编程方式选择或随机化哪个符号替换哪个点。有关此示例,请参阅 地图中的图钉。绘制圆圈
绘制选项为您提供了多种方法来执行一些非常基本的操作… 绘制圆圈。例如,您可以通过其圆周上的任意点绘制一个圆圈。因此,您需要计算一个中心点和一个与第一个点相距半径(例如 25 像素)的第二个点。
|
![]() |
|
![]() |
-draw
” 操作,或者使用 上下文推送。使用椭圆,您可以直接指定半径作为轴长度
|
![]() |
stroke-linecap round
' 的线来生成一个圆形。然后,笔划宽度将设置圆形的直径。请注意,该线必须具有一定的长度(无论多小),否则绘制将不会绘制任何内容。
|
![]() |
|
![]() |
M
' 来定义中心,其余路径组件中的 '25
' 和 '50
' 定义了相对于该中心的圆形半径和直径。![]() ![]() |
相对移动 SVG 路径 项目 'm ' 在 IM v6.4.3-5 之前被破坏。如果您的 IM 版本早于此版本,圆形可能仅显示为单个像素。您可以通过将上述内容中的 'm ' 替换为 'l ' 来解决旧版本中的此问题。 |
|
![]() |
|
![]() |
|
![]() |
绘制箭头-- 定位、旋转和缩放符号
使用上述技术,您可以创建特殊的符号,例如箭头,您可以定位这些符号,使其尖端位于线的末端,并绘制在其上面。如果您在绘制线之后绘制箭头(典型情况),则箭头将绘制在线的顶部。但是,有三种类型的箭头可以定义,每种类型的定义方式根据其用途而有所不同。- 测量,您只需在某工程图中用箭头标记线的末端以指示测量的范围。非常简单。
- 矢量,显示某个值的朝向和强度。
例如,在天气风力图中。需要一个尾部,并且 0,0 点是尾部的末端。通常会创建这样一个矢量的大网格。 - 指示器,指向某个细节。
对于此,0,0 点可能应该是箭头本身的尖端,或者是在箭头前面的一定距离。
测量箭头
在线的末端添加箭头头相对容易。您基本上创建了一个 '箭头头' 符号,并将其绘制在正确的位置。例如...
|
![]() |
path
' 定义中移出的优点,允许您将整个路径指定为 '常量'...
|
![]() |
|
![]() |
|
![]() |
-draw
" 操作中完成所有这些操作。假设绘制一条线,然后在两端添加箭头,需要不同的颜色集、位置、旋转,甚至可能不同的比例。这意味着我们需要将画布扭曲的范围限制在每个箭头头的绘制范围内。如果您不限制范围,您可能会开始影响以后的绘制操作,并且永远无法确切知道您正在生成什么。为了限制扭曲的范围(以及所有其他绘制属性),您将相关部分包装在 "graphic-context
" 中...
|
![]() |
push
' 本质上将所有当前绘制属性保存起来,以备将来使用,而 'pop
' 恢复这些属性,用先前保存的设置替换任何设置(颜色、扭曲、位置等)。这意味着在 '弹出' 后,'画布扭曲' 被取消,绘制将恢复到修改之前所处的状态。上述技术只是生成箭头的众多方法之一,当将箭头作为测量距离的一部分进行绘制时,这是一种很好的方法,例如在技术图纸中。矢量箭头
如上所述,矢量显示某个值的朝向和强度。这意味着箭头的长度是可变的,并且箭头头可以位于距矢量起点几乎任何位置。现在您可以做一些繁重的数学运算来计算给定矢量长度和角度时箭头头应该放置的位置,但有一种更好的方法,让 ImageMagick 为您完成这些计算。解决方法是在 扭曲的画布空间 中绘制矢量长度作为正确长度的水平线。绘制完该线后,只需再次将绘制空间平移到线的末端,而画布保持 '扭曲'。现在您已正确定位,并具有正确的旋转来像往常一样绘制矢量的 '箭头头'。例如,这里我以 -35 度角生成一个 70 像素长的矢量。
|
![]() |
指示箭头
在上述内容中,我还演示了一个指向先前矢量箭头起点的指示箭头。但是,我没有像以前那样绘制箭头,而是将其创建为一个反向箭头符号,该符号从原点(或起点)向后偏移 10 像素。也就是说,符号位于我要指示的位置,所以我实际上不希望箭头直接位于该位置的顶部,而是稍微偏离它。现在,虽然指示器比矢量更容易处理,通常不需要可变长度,但您通常希望在指示器的远端添加文本以指定要指示的内容。像以前一样,计算该位置可能很困难,所以为什么要费心呢?定位文本的解决方案与矢量相同。保持用于绘制指示箭头的原始扭曲空间,并将原点平移到该箭头的尾端(扭曲空间中水平偏移 40 像素)。现在我们已经重新定位了,我们可以绕着新位置取消扭曲的旋转,这样您就可以像往常一样绘制文本(稍微偏移一点)。不幸的是,虽然默认的文本对齐方式 'left' 在上面有效,但您目前无法在 MVG 中将文本对齐方式指定为与重力分开的设置。如果这是一个问题,请在 IM 错误论坛上提出请求,希望文本对齐方式(与重力定位分开)将成为现实,尤其是因为它实际上是 SVG 规范的一部分。绘制对象
宽阔的彩色描边
您不必用路径或轮廓完全封闭填充区域以创建各种形状。使用非常大且宽的 笔划,您可以在画布上生成大的区域和颜色样本。例如,一个宽笔划椭圆弧可以生成一个很好的颜色区域,我实际上已经看到它被用于创建海报。
|
![]() |
|
![]() |
圆柱体
在 IM 论坛讨论 中,人们对使用 ImageMagick 绘制命令绘制圆柱体,特别是阴影圆柱体进行了热烈的讨论。绘制圆柱体的诀窍是绘制 'roundrectangle
' 原语,使端点形成椭圆形。也就是说,如果圆柱体宽度为 50 像素,则分别将矩形的角圆角设置为 25 和 12 像素。也就是说,矩形宽度的二分之一,然后再次二分之一。因此,圆柱体只是两个彼此叠加的圆角矩形。第二个较浅的填充颜色 '末端椭圆' 的尺寸正好是两个角尺寸的两倍。例如...
|
![]() |
|
![]() |
cylinder_bar
",生成一个圆柱体百分比条...该脚本可以生成任何大小的图像,根据该大小和其他在脚本顶部定义的设置适当调整所有参数。它还包括 '玻璃厚度' 的概念,用于在封闭的半透明玻璃圆柱体和内部的彩色圆柱体之间创建一个间隙。请注意圆柱体的非常微妙的阴影,尤其是在绿色圆柱体的末端与玻璃圆柱体的末端重叠时!令人惊讶的是,您只需要一点点预见就能做到。在文本字符串中绘制特殊字符
使用引号还是反斜杠?
人们在使用 -draw 时遇到的最大问题之一是绘制对 UNIX shell 和 DOS 命令行甚至其他语言(如 C、Perl、PHP、R 或 Visual Basic)具有特殊意义的字符。在这方面,最大的罪魁祸首是两种类型的引号字符,以及变量替换字符,如美元符号 '$
' 和 shell 和 ImageMagick 转义字符,反斜杠 '\
'。基本上,因为 "-draw
" 的 MVG 参数需要引用,并且 'text
' 字符串参数也可能需要一些额外的引用。为了解决这个问题,用户通常使用两种不同的引号字符,一个用于 shell,另一个用于 MVG 文本字符串。-draw '... text 0,0 "string" ...'
-
-draw "... text 0,0 'string' ..."
$
',无需转义。选择正确的形式可以解决大多数问题,但有些字符仍然存在困难,并且每种解决方案都取决于您使用的引号集,因为它们也定义了如何转义特殊字符。以下是四种引号情况和特殊字符处理……- 对 shell 参数使用单引号,
在 MVG 文本字符串周围使用双引号。处理绘制文本字符串最简单的技术是使用单引号作为包装 shell 参数。但是,这意味着要包含绘制字符串中的撇号,您需要退出 shell 的 '单引号模式',并在 shell 的单引号之外提供该撇号。例如,以下是处理我提到的四个特殊字符的方法。magick -size 250x50 xc:none -box white -pointsize 20 -gravity center \ -draw 'text 0,0 " '\'' \" $ \\ " ' \ -trim +repage text_special_sd.gif
- 对 shell 参数使用双引号,
在 MVG 文本字符串周围使用单引号。如果您确实想将 'shell 变量' 插入到绘制字符串中,那么您将不得不对外部 shell 参数使用双引号。这使得整个事情变得更加复杂,因为您失去了 shell 的保护,您现在不仅要转义美元 '$
' 符号,还要转义反斜杠 '\
'。另一方面,shell 就不再需要使用单引号字符作为其参数结束的定界符,因此这方面得到了简化。让我们总结一下我们对特殊字符的简短列表的结果。magick -size 250x50 xc:none -box white -pointsize 20 -gravity center \ -draw "text 0,0 ' \\' \" \$ \\\\ ' " \ -trim +repage text_special_ds.gif
- 对 shell 参数使用单引号,
在 MVG 文本字符串周围使用单引号。让我们用最后两种引号组合的总结来结束这个话题。我会让您自己弄清楚它们是如何由 shell 和 MVG 解码的。magick -size 250x50 xc:none -box white -pointsize 20 -gravity center \ -draw 'text 0,0 '\'' \'\'' " $ \\ '\'' ' \ -trim +repage text_special_ss.gif
- 对 shell 参数使用双引号,
在 MVG 文本字符串周围使用双引号。magick -size 250x50 xc:none -box white -pointsize 20 -gravity center \ -draw "text 0,0 \" ' \\\" \$ \\\\ \"" \ -trim +repage text_special_dd.gif
-draw
" 命令行参数必须同时处理命令行 shell 以及 MVG 文本字符串中的反斜杠和引号转义。结果可能会令人困惑和棘手。请记住,shell 对两种类型的引号的处理方式不同,而 MVG 文本字符串则不会。当然,在复杂的脚本中,更好的方法可能是完全避免 shell 和任何脚本问题。您可以通过从 MVG 绘制文件读取 "-draw
" 参数来做到这一点。-draw @drawfile.mvg
|
|
![]() |
|
![]() ![]() |
MVG
" 文本文件之一。它不包含 shell 转义或引号。因此,只有 MVG 引号和转义存在。请注意,在上面,如果我对 MVG 文本字符串使用单引号,唯一的变化是,我需要对字符串中的单引号字符进行反斜杠转义,而不是对双引号字符进行反斜杠转义。 关于百分号字符 关于 "-draw
" 文本运算符中的特殊 '转义' 字符,最后一点。百分号字符 '%
' 应该按原样绘制。您不应该需要做任何特殊的事情来绘制它们。如果它们没有按原样绘制,那么您拥有的是旧版本的 IM,应该尽快升级。![]() ![]() |
直到 IM 6.2.4 版本,'% ' 字符被用作转义字符,用于在绘制的文本字符串中包含额外的图像信息。现在不再是这种情况,因为当 SVG 图像也尝试绘制百分号字符时,这种转义会令人困惑且不正确。 |
\n
' 换行转义)被认为与 "-draw
" 运算符和 MVG 格式用于处理 SVG 图像格式的预期用途不兼容。因此,从 IM 6.2.4 版本开始,% 转义不起作用,反斜杠只转义自身和周围的引号。
|
![]() |
-draw
" 时如何避免它,请参阅 绘制百分号错误 页面。 使用注释而不是绘制 避免这些类型问题的更好方法是使用 "-annotate
" 而不是绘制文本绘制。此运算符是绘制运算符的包装器,允许使用绘制的所有功能,但形式更简单。基本上,此运算符只需要一组引号(用于 shell)。这使得处理特殊字符变得非常简单。不幸的是,虽然您不再需要为 IM 转义引号,但您现在有了 百分号转义,例如 '@
' 文件读取、'\n
' 换行符和其他百分号转义扩展。例如,使用单引号……
|
![]() |
|
![]() |
@
' 转义从文件读取字符串,则所有注释引号和转义将被完全忽略。例如,这里我们包含有关图像宽度和高度的信息!
|
![]() |
|
![]() |
IM 和 SVG 处理
SVG 输入驱动程序:RSVG 与 MSVG
处理实际的 SVG 图像格式是一项非常复杂的工作。引擎需要处理所有方面,如 SVG -- 可缩放矢量图形 文档中所定义。这需要大量的编程工作和时间。因此,ImageMagick 在处理 SVG 格式图像时提供了两种方法。第一种方法是使用开源 RSVG 库,将 SVG 格式神奇地转换为 IM 可以轻松处理的栅格图像。此引擎几乎在 SVG 处理的各个方面都已完成。第二种方法是让 IM 尝试使用称为 MSVG 的内置方法将 SVG 奇妙地转换为 MVG。MSVG 尝试将 SVG 图像神奇地转换为 IM 的 "-draw
" 运算符的 "MVG" 绘制语言。绘制 MVG 的许多功能都是专门为此目的而创建的。不幸的是,虽然基本线条绘制和颜色存在,但它远非完整的 SVG 转换器。您可以通过使用特殊的输入格式 "MSVG:
"(添加到 IM v6.3.4)来读取 SVG 图像,从而强制使用内部 MSVG 转换器。但是,如果存在 RSVG 库,大多数 ImageMagick 会使用它来渲染 SVG 图像。要找出您的 IM 会做什么,请使用……如您所见,括号中的 "RSVG
" 表示我自己的 IM 将使用 RSVG 库,该库存在于我的计算机上,并提供了给定的版本。在这里,我 '绘制' 一个小型的手工 SVG 图像,"diagonal.svg"(由论坛用户 penciledin 贡献),它在白色背景上创建了一个带有简单对角线渐变的矩形。
|
![]() |
但是,如果您使用内部 MSVG(如果不存在 RSVG 库,则为默认值)来渲染它……
|
![]() |
- 非垂直渐变(没有转换为新的 MVG 渐变处理)
- 沿着曲线路径的文本
- 文本对齐(与重力分开)
SVG 设置
SVG 图像格式是一种矢量格式(请参阅 关于矢量图像格式的说明),因此图像通常没有默认 '大小'。相反,它是在特定 "-density
" 下 '绘制' 或 '渲染' 的,就像 PostScript 一样(默认密度为 72 dpi)。此外,如果 SVG 没有 '绘制' 背景,您可以通过使用 "-background
" 设置来指定要使用的背景颜色。例如,这里还有另一个小型 SVG 图像 "home.svg
",它已使用 3 种不同的密度和 3 种不同的背景(包括透明背景)进行 '渲染'。
magick -density 36 home.svg home_1.gif magick -background skyblue home.svg home_2.gif magick -density 144 -background none home.svg home_3.png |
![[IM Output]](home_1.gif)
![[IM Output]](home_2.gif)
![[IM Output]](home_3.png)
![]() ![]() |
我发现一些 SVG 图像无法缩放。也就是说,它们已经根据 '像素' 定义了术语,而不是使用现实世界的长度,例如 '点'、'英寸' 或 '毫米'。因此,虽然 "-density " 设置可能会更改总体图像大小(以现实世界的单位表示),但 '像素' 的大小不会改变,因此图像本身的大小也不会改变。然而,这种 SVG 图像非常罕见。更糟糕的是,一些 SVG 图像混合使用 '像素' 和 '点' 测量单位,除非作者是故意这样做的,否则如果您尝试将其用作与作者意图不同的密度,您可能会得到一团糟。幸运的是,这些情况更少。 一个简单的解决方法通常是将 SVG 中的所有 '像素' 单位更改为 '点',但这不应该盲目进行,以防 '像素' 的使用是故意的。 |
SVG 输出处理
从 IM v6.4.2 版本开始,IM 可以将任何位图图像转换为 SVG 矢量图形!转换并非总是成功的,但较大和/或较简单的图像(如位图蒙版)会转换得很好。例如,这里我将一个糟糕的位图形状转换为 SVG 图像,然后再次将其转换为位图,以便将位图平滑为适当的抗锯齿形状。
magick -pointsize 72 -font Candice label:A -threshold 50% \ -trim +repage -bordercolor white -border 5x5 A.gif magick A.gif A.svg magick A.svg A.png |
![]() |
![]() |
|
![]() |
![]() |
AutoTrace
" 库,并将 IM 配置为使用 "--with-autotrace
" 开关。如果未安装 "AutoTrace
" 库且未将其编译到 IM 中,则生成的 SVG 输出将是大量单像素圆圈,生成二进制结果,而不是平滑的 SVG 轮廓图像。与之相比,此类图像非常庞大,通常需要很长时间才能由 SVG 渲染器渲染。实际上,需要更好的默认栅格到矢量技术。可能使用形态学骨架和 MAT 技术。有一个 "autotrace:
' 输入委托,用于“平滑输入位图图像”,该委托使用 "autotrace
" 命令直接一步完成以上所有步骤。但是,我上次查看时,该委托消失了。这就是你使用它的方式...
|
![]() |
autotrace
" 命令中获得 SVG 输出,只是将输入图像通过 SVG 过滤以使其平滑。作为替代方案,你可以直接使用 "autotrace" 命令,如示例 栅格到矢量边缘 和 使用 Autotrace 的骨架 中所示。你可能还希望查看 cancerberosgx 在 生成 SVG 图像 中的结果,他研究了将照片转换为矢量图像的解决方案。非 IM 矢量图形编辑器
ImageMagick 是一个像素数组处理器,它通常不会保存矢量图像('MVG' 是唯一的例外),只会读取它们并将其转换为像素数组。对于其他像素图像编辑器(如 Gimp、Photoshop 等)也是如此。对于编辑和处理基于矢量的图像,请使用以下程序Sodipodi | 基于 SVG 的矢量图形编辑器 |
Xfig | 简单但非常好的矢量对象编辑器 (非常适合制作标志、地图以及在页面上排列照片) |
Dia | |
AutoTrace | 将位图数组中的形状转换为矢量轮廓 |
Sketch | 基于 Python 的矢量编辑器,支持曲线文本。 |