ImageMagick中文使用手册:基本用法教程
本文将为你详细介绍ImageMagick软件所遵循的命令行处理规则、一些新的图像处理功能、它的使用理念和方法,以及该软件内部究竟是如何运行的。
详细了解这些背景知识可以让你更好的理解网页中的例子,即使只使用程序的API,这部分也是值得认知和理解的。
ImageMagick的命令行处理介绍
命令行样式改变的原因(或者叫IM以前的版本存在的问题)。
在ImageMagick以前的版本(版本5.5.7及更早的版本)中,命令行界面连接IM的程序库倾向于使用命令参数呈现的顺序。但这是非常随机的,也让所有试图弄清软件究竟是如何运行的人感到困惑。另外,运行成功的命令可能在下一次不能运行,但作为IM的创始人,始终不懈地改进接口,以让它像人们所期望的那样工作。
问题的根源在于ImageMagick所遵循的是相当标准的UNIX命令行处理格式
command [options] input_image output_image
随着时间的推移这也开始产生问题,因为图像处理是会进行大量操作,且对其执行的操作往往涉及多个图像的复杂对象。基于这个原因,命令行处理样式也开始改变。
command [options] image1 [options] image2 [options] output_image
这个能够在新版的软件中运行,并且是版本5.5.7中所使用的基本样式。
各种各样的图像操作参数如“-negate”、“-resize”和“-crop”等,会在图像导入之前或者之后使用。
例如,在版本5.5.7中,以下两条命令都是可行的并且可以达到同样的目的:
convert -negate image.gif output.gif convert image.gif -negate output.gif
问题是如果进行两个图像处理操作,例如:
convert -size 40x20 xc:red xc:blue \ -append -rotate 90 append_rotate.gif
在版本5.5.7中的结果是:这两个图像首先将被旋转,然后连接到一起,将产生如下的图像。这说明”-rotate”操作将在”-append”之前进行,而这可能并不是使用者所预想的。
而在ImageMagick版本6中,操作将永远按照使用者所给定的命令行顺序运行。这样之前的例子在版本6中,两个图像将首先被连接到一起,然后得到的图像将进行旋转,产生的图像为:
如果使用者想在两个图像连接到一起之前旋转,他可以明确地要求IM版本6按如下顺序操作:
convert -size 40x20 xc:red xc:blue \ -rotate 90 -append append_rotate_bad.gif
这种良好的控制方式超越了IM之前的版本,只是可能额外需要一个管道或者介质保存图像来实现。
要解决这个问题,需要大量的工作并克服兼容性的问题。但另一方面则是解决了在版本5中所应用的简单命令无法如版本6那样符合我们预期的运行。
实质上,命令行的用法在版本6之前的版本中并未界定清楚,在我们的定向思维被打破之前,产生了许多奇怪和意外的结果。
IMv6命令句法
在操作图像之前,至少应该有一个图像被读取或者创建,事实上你也可能考虑将图像的读取或者创建看作同一个操作。
这意味着IMv6的句法可以简化为:
command { [-setting]... "image"|-operation }... "output_image"
{…}表示根据你的需要引入多次图像读取或操作,并根据命令顺序对图像进行处理。
选项类型——操作符和设置
可以从The Anatomy of the Command Line的 ImageMagick Website 中获得下文的总结。
所有命令行选项都可以分成以下的设置选项和图像操作符两类,设置选项设定相关的参数值,而操作符则实际上预制一些功能。
设置选项:是在其它图像操作之后使用,仅储存信息的命令行选项。这也就意味着它仅仅是设定相关的参数值供之后使用。其中许多的选项都有一个“+”和一个“-”的样式。后者通常是用来关闭设置,或将其重置为默认状态,这使得操作者能迅速且简单取消设置的效果。例如”+gravity”将使重力的设置恢复到其最初的没有重力的状态。设置又可以进一步划分为多个子类别。
操作设置:控制着后续的操作如何运行。操作设置设定颜色、操作者所使用的字体、图像和文本的放置、源图像中颜色的查找、更为复杂的操作的处理方法等等。
-dither -gravity -fill -background -bordercolor -stroke -font -pointsize -strokewidth -box -virtual-pixel -interpolate
绝大多数的设置选项都属于这一类别。
输入设置:专门控制被创建或者读取的图像的生成。它们通常被用来分配和重写与设定产生的图像相关联的特定元数据。
它们从外部文件中创建或者读取。
-label -delay -dispose -page -comment -size
要注意的是,这些都只会在图像被创建或者读取之后才会执行。
“-set” 这个特殊的操作将在图像被读到内存或者经过其他处理之后更改图像的元数据,可以从下面的Meta-Data中获取更为详细的相关信息。
输出设置:只在写入或保存图像到磁盘时使用。尽管它可以在命令行中的任意位置出现,也只是在图像被写入时才被使用,通过作为默认的图像文件名来实现,或者通过”-write”或”-identify” 操作。
-quality -loop -compression -format -path -transparent-color
如果没有设置,或者通过“+”的形式关闭,将使用其相应的默认形式。这个默认形式通常是被读取的最后一个图像保留下来的参数。
如果文件格式要求,诸如”-background”色等的操作也将被指派到图像中。
控制和调试设置:控制着IM如何执行其任务,包括:
-verbose -debug -warnings -quiet -monitor -regard-warnings
有关这些特殊设置的详细信息见下面的 IM Operation Controls。
图像操作符:是修改图像的命令行参数,当这一命令出现的时候将被立即执行,并且可能使用在命令行出现过的其它的设定选项。
这些操作符可以被分为一些子类别:
图像生成操作符:将从文件或其它介质中读取图像或生成新的图像,这些包括:
image.png xc: canvas: logo: rose: gradient: radial-gradient: plasma: tile: pattern: label: caption: text:
作为操作符,它们同样地在命令行中出现的时候将立即被执行,但只是添加新的图像到内存中,而不会改动以前读取过的图像。
当然,作为操作符,之前所定义的任何设置都将被应用,特别是控制文件和文件流输入的输入设置。例如,”-size”确定了你想创建的图像的大小,而如”-delay”和 “-page”则定义和重写元数据。
简单图像处理操作符:将修改所有被读到内存中
的图像,并且每一个图像都被单独修改。包括:
-crop -repage -border -frame -trim -chop -draw -annotate -resize -scale -sample -thumbnail -magnify -adaptive-resize -liquid-resize -distort -morpohology -sparse-color -rotate -swirl -implode -wave -flip -flop -transpose -transverse -blur -gaussian-blur -convolve -shadow –radial-blur -motion-blur -sharpen -unsharp -adaptive-sharpen -adaptive-blur -noise -despeckle -median -negate -level -level-color -gamma -auto-level -auto-gamma -sigmoidial-contrast -normalize -linear-stretch -contrast-stretch -colorize -tint -modulate -contrast -equalize -sepia-tone -solarize -recolor -opaque -transparent -colors -map -ordered-dither -random-dither -raise -paint -sketch -charcoal -edge -vignette -emboss -shade -poloroid -encipher -decipher -stegano -evaluate -function -alpha -colorspace -separate
由于当图像操作符出现的时候就会被立即执行,所以应该出现在图像已经被读取到内存之后。如果不止一个图像被呈现,这些图像将一个一个按顺序操作。因此对在当前图像序列中是哪些图像应该十分谨慎。
这些操作符生成多个图像是极有可能的。例如”-crop”可以生成多个图像的源代码,”-separate”则将图像拆分为单独通道的图像,因此有可能在内存中得到更多的图像,但是所有这些操作符一次只针对一个图像。
而许多API的等效操作只针对图像列表中的第一个图像,也就是说它们不会遍历每个图像。但转换和其他CLI命令,则是按顺序遍历图像序列中的每个图像。
多图像序列操作符:的特殊在于它们将当前的图像序列当做一个整体进行修改。它们可以以一个单独的组合图像替换整个图像列表,或者根据前后的图像对该图像进行修改。它们使用于阿尔法通道、动画处理和颜色通道处理等。
-append -flatten -mosaic -layers -composite -combine -fx -coalesce -clut -average -evaluate-sequence
因为图像序列是被作为一个整体在进行处理,一些图像将被删除或者替换,上述大部分的操作符最终将多个图像合并为单个图像。
Layers composite方法是目前唯一的能将当前的图像序列拆分为两个完全不同的图像序列,然后将它们合并为新的图像序列的操作符。这种拆分基于一个特殊的空:图像标记。
这些操作符都不能使用于”mogrify”命令,因为这个命令将一系列输入的图像作为单个图像进行处理。
图像堆栈操作符:影响内存中当前图像的顺序以供处理,它们和之前的Image Sequence Operator在很多方面都很相似,但是它们并不对图像本身进行处理,而只是调整图像的顺序。
( ) -delete -insert -swap -reverse -duplicate -clone
其中的圆括号可能需要应用反向斜线或者引用,防止CLI赋予任何特殊的含义。
这些操作符都不能使用于”mogrify”命令,因为这个命令将一系列输入的图像作为单个图像进行处理。
各种各样的特殊操作符:和之前的操作符相比,是显得不同寻常或不标准的。
-geometry -version -list -bench -concurrent -preview
“-geometry”是是唯一一个仅仅影响图像序列中的一个图像(最后一个图像)的而不是影响所有的图像操作符。它仅适用于向后兼容性和特殊的阿尔法通道要求,请见 Geometry, resize just the last image,已获得更多的信息。
“-version” 和”-list” 是信息生成操作符,并使IM在返回请求信息之后退出。请见下面的 IM Special Controls,以获得更多关于这些选项的信息。
有一些选项能够使整个命令多次执行,基本上以某些奇怪而又不寻常的方式特殊地处理。
通常,除了某些特殊情形或者恢复特定的全局信息,这些操纵符都不被用到。 我希望选项是被明确的分为设置和操作符,因为这对IM的运行至关重要。
记住这是在ImageMagick版本6中。
设置将以某种方式保存供以后使用,而操作符立即运用到图像。
这是版本6和之前的所有版本都不同的原因之所在。所有的选项都被定义为设置或者操作符,定义的顺序决定了该选项在什么时候,在什么图像中使用。
IM Examples Options Reference 可用来区分设置和操作符。
IM命令的运行示例
让我们来看一个IM版本6是如何运行的范例。
convert eye.gif news.gif -append storm.gif tree.gif \ -background skyblue +append result.gif
让我们分解下这个命令来看看IM版本6究竟是如何运行的。
参数操作效果
参数 操作效果 图像数 convert 初始化并创建一个空的图像序列 空的图像序列 eye.gif 读取图像,并将图像添加到当前图像序列的末端 1个图像 news.gif 在序列中添加第二个图像(现在有了两个图像) 2个图像 -append 将当前序列中所有的图像垂直连接在一起 所有图像被单个图像替代 1个合并的图像 storm.gif 在图像序列中添加一个图像 2 tree.gif 再添加一个 3 -background skyblue 设置背景颜色供之后使用,不对图像做任何更改 3 +append 将3个图像水平连接,用背景色填充空白区域 1个合并的图像 result.gif 作为最后一个参数,它完成的功能就是将图像信 息写入文件中。图像序列中的单张图像将会写 入这个给定的文件名和格式的图像文件中 写入
正如我们所看到的,ImageMagick版本6当中的操作非常直截了当和有逻辑性,使操作的结果可以预知,这就是关键之所在。
传统的命令行样式
由于大量的IM的脚本都使用单个的图像操作符
command -operator input_image output_image
在读取图像之前就应该确定要使用的操作符。
在处理这种传统情况时,IM将所有出现过的图像操作符储存起来,当在命令行中出现的时候,就会应用到第一个图像。当你写下如下命令时这些会运行:
command input_image -operator output_image
例如这个传统命令:
convert -flip storm.gif cmd_flip_legacy.gif
和版本6中的这个命令生成的结果是相同的:
convert storm.gif -flip cmd_flip_postfix.gif
这些传统的命令样式也可以运行,但是存在和版本5中同样的问题。所有的设置都适用于第一次读取之前,而所有的操作符都存储着直至第一个图像被读取之后使用(只针对第一个图像)。也不能保证多个操作符运行的顺序会与你写入时的顺序相同。
此外,所有的操作符都被存储起来,直至第一个图像被读取,才会全部应用,在读取图像之前多次重复一个命令,可能导致一些早期命令消失,
这不是一个错误,但是是对IM传统功能的一个错误使用。
这种样式的命令行只有老版本支持,所以并不推荐使用,因此如果可能的话,应该尽可能地避免使用。任何包含这种传统样式的脚本,都应该在将要使用的操作符之前进行更新。
这种老版本不会在IM版本7中出现,IM版本7的计划包括命令行单通道处理,这反过来将允许从文件和管道读取图像处理选项的使用。但是单通道处理技术并不会允许操作者在读取文件之前使用,如果使用的话,可能会产生无图像的错误。
命令行vs API
IM的命令行和Magick API的PerlMagick, RMagick, PHP IMagick 和 MagickWand等存在很多区别。
只有一个图像列表或序列
在命令行只能有一个可在任何一个时刻处理的图像列表或序列。
操作者可临时增加或者保存一个图像(见Parenthesis和MPR: Named Memory Registers),甚至可以克隆入栈后的图像序列,但是不能同时对两个图像序列进行处理。
而API的语言则允许操作者有多个单独的图像列表,为了更好地处理图像,通常将每个图像都单独保存为序列,只有当需要的时候才把这些单独的图像序列合并到一起或者是作为操作的最后一步。也可以按任意顺序操作,并将其存储到数据库或者其它数据工具,用于排序或者以后比较。
在命令行中,只有一个图像列表意味着不能按任意顺序操作,而是按照逻辑顺序,完成所有的图像处理步骤。这意味着返回或者后来再进行修改、对图像序列处理之后的结果进行按照不同的顺序来进行修改比较困难,
将两个完全单独的图像列表合并成一个逻辑整体尤为困难,但是可以让操作者在命令行中完成此操作的技术已经出现。
像素数据直接访问
同样的,可以从命令行中对图像进行一些数学处理或者合并像素数据,但是不能轻松地使用命令行界面查找属性、读取或修改特定像素和区域。
你可以使用特殊的 FX Image Operator对图像的像素进行合并或者修改,但是一般只限于转换整个图像,而且非常慢。
为方便 FX Image Operator用户使用,许多常见操作被内置入IM,创建了Color Lookup Tables, Evaluate Math Functions, Multi Argument Functions和General Image Distortion Operator以及一些特殊的Image Composition Methods。
API’s则以更为直观的方式处理图像,使用户能更容易地以API提供的额定频率自制单独的一套操作。
条件处理
IM的命令行界面不能轻松地对某些具有图像派生属性的图像进行修改,例如它很难基于图像是使用了浅色背景还是深色背景来进行差别处理。
你可以运用 FX Image Operator来进行有限的特定的条件处理,或者在特定条件下调整一个图像的方向,或者利用放大和缩小来改变图像,但这些只是处理特殊的和众所周知的处理条件。
进行条件处理唯一真正实用的方法是使用单独命令和临时文件。此示例请参阅注释良好的Jigsaw Script。
API’s将所有相关图片存储在内存中,当需要的时候,在特定情况下,能进行这种类型的条件操作。
遍历处理
你不能仅仅以一种特定的方式对图像进行遍历,也不能轻松地修改正在处理的图像序列中的图像。也就是说,你不能简单地根据每个图像的编号或者以前图像处理的结果来进行不同的处理。例如绘制不同大小的图像,逐渐模糊图像,或以单一的命令生成一个动画序列。
你可以在一个图像序列中修改特定图像,示例见 Frame by Frame Modification of an Animation。但是你必须知道该图像列表中有多少图像。
在命令行中遍历图像的唯一真正实用的方法是将单个的图像写成单独的图像文件(见Writing a Multi-Image Sequence),然后在外部脚本循环中一个个处理。示例见Divide an Image Vertically中的shell脚本。
或者可以使用shell 脚本循环来生成图像,并通过管道将结果合并到最终的图像或者图像序列。示例见Layered Images Examples中的shell脚本,或者各种 Warped Image Animations中的shell脚本生成器。
API’s在多个图像遍历中没有任何问题,无论是在一个单一的图像序列,还是多个单独的图像序列,甚至是一个数组或者数据结构的图像序列。它还可以保存内存中的所有图像,供图像最后的结合步,无需管道输送,或使用临时文件。
如果你的应用需要进行这些操作(尽管很少的应用需要这些),API也许是一个不错的选择。
“conjure”程序(见下)的最初目的是为了ImageMagick更好的脚本运行,使之能够处理多个图像列表。改进了的IM版本6几乎让试验中的API废用,虽然它还可得并且在不断改进。
参数处理
除了文件名和命令行选项,只有几个基本的选项参数样式在被使用:
常量名 (对于特定的设置和方法类型) 常量名列表 (例如两种颜色或者渠道) 几何参数 (带标记数字的特殊格式化列表) 浮点列表(有时百分号转义) 自由字符串(百分号转义)
常量名
常量名是特定的字符串常量用于查找内部的可能被一个选项用到的设置的程序库。
例如”-gravity”设置可以接受任何9个不同的设置,一旦设定,这个设置将被所有的图像处理操作运用,例如“北”、“东”或者“东北”的设置。
你可以通过 List Operational Option (见下)获得所有有效设置的列表,如使用以下命令:
convert -list gravity
只有特定的设置是允许的,如果你尝试使用其它的设置,将得到错误,例如:
convert xc: -gravity Invalid null:
在IM中,设置可以以不同的方式指定,所有的这些都是有效的。例如,设置中可以指定大写、小写或两者的组合。单个词语(在”-list”中指定为大写字母)可以有多余的空格、 连字符或下划线,这些都将在操作中被忽略(但只是词语之间的)。
因此”North East” “-gravity”等后续的参数都是有效的。
‘NorthEast’, ‘northeast’, ‘NORTHEAST’, ‘NorTheAst’, ‘north east’, ‘north-EAST’, ‘NORTH_EAST’, ‘ North East ‘, ‘___North___East___’.
但是’Nor The Ast’不是有效的参数,尽管所有的字母都是正确的,但空格放错了位置。
这些常量名称不只用于设置,它们申明的操作方法,也将在一些更为复杂的图像处理中使用。如”-layers”、”-distort” 和 “-morphology”。
许多常量名都从外部文件读取,例如,颜色名称如”-fill”、”-stroke”、”-background” 和 “-mattecolor”,或者用于”-ordered-dither”的特殊的’threshold’地图。此外, “-list” 可用来查询当前安装的IM版本中所有的常量名。
常量名列表
这是一个较少使用的参数,通常用于如颜色调整等需要一种或者两种颜色的设置,”-level-colors” 选项可以使用以下的任意参数样式。
color color1,color2 color1-color2
当可以指定具体命名的通道时,另一个大量使用的选项是通道选择。例如:红、绿、蓝、黑和阿尔法。这个选项也采用以单个字母的字符串指定的列表,如RGBA。
几何参数
这是最常见的形式或者选项参数,通常用来指定大小、矩形和各种操作的偏移量。它们还用于任何需要1至5的列表的选项,不论是整数还是浮点数。
比如”-crop”和”-resize”选项将使用几何参数的完整句法,而”-border”、 “-level”和 “-gamma”等则只使用几何参数的小部分句法。
这种类型的参数是如此普遍,但是又相当特殊和复杂,因为使用了内部解码器将参数解码为比输入的字符串更易使用的形式。
这个参数允许用户指定一个至多包含5个浮点值的参数(尽管大多数操作符只能使用整数),以下所有的都是经过解码器解码的字符串形式:
WxH+X+Y WxH +X+Y A A/B/C A,B,C,D,E
用户可以以上面的任何形式来指定这个小的数字列表,但是具体哪种形式被采用取决于操作中这个参数的用途。
前面的几个通常用于规定特定的大小和位置,或者只是某种目的的偏移量。
“+X+Y”的形式,则实际上被解码为第三个和第四个参数,而第一个和第二个参数则因未设置而为空。
最后的几个形式中,最多可输入5个值,通常用来指定标准的RGBKA 的图像通道值。
在这些数字中,解码器还会显示出是否有带有特殊标志的数字(%’, ‘^’, ‘!’, ‘<‘, ‘>’ 中的任意形式),但只是在字符出现的时候报告,但并不报告其在参数中的位置,例如,IM并不会记住’% 是在哪个特定的数字上,而只是显示它是存在的。而且如果多次出现,也不会重复报告。
这就意味着’%50’的几何参数和’50%’的含义是相同的,尽管我们可能更倾向于后者的读法。
同样的,’50%x30’可能实际上意味着’50%x30%’,而不是你所认为的图像宽度的50%和30像素高。
几何参数可能包含特殊的“%”标志,目前无法基于图像属性设置运用百分号转义来设置其值。
现在有关于百分号转义扩大来解决几何参数中的这个问题的未来建议,希望这将是IM版本7的一部分。
浮点列表
如果需要5个以上的浮点数,甚至是未知值的数,浮点列表参数将被使用。虽然目前这些都是由不同的选项分解完成,但是从选项到选项之间也会有细微的变化。
它们通常由一个浮点数被逗号或者句号分开的字符串(通常为引用的)构成。Distort Operator是最著名的浮点数列表,其它还有 User Defined Morphology Kernels。
浮点数的一个变形被”-sparse-color”使用,允许用户用颜色替代某些浮点值。当生成的数组传递到程序库时,在内部仍然被转换成浮点值。
自由字符串
无论是生成的标签,标注的文字,还是保存为图像元数据,许多选项只是将字符串作为一个参数。
这些通常包括在字符串使用之前被替代的百分号转义,有可能是立即替代,也可能是稍后替代,但是一定是在参数使用之前。(见 Delayed Percent Escapes)
有百分号转义的参数
由于其性质,最后的两个参数类型往往都预先处理,以扩大字符串中的 Image Properity Percent Escape。
这意味着特定的字符序列将扩大(字符串替换或取代)到其它字符串或者被处理图像正查询或者计算的值。
这通常是在浮点列表被解码或者自由字符串被涉及到的选项运用之前进行。
如果允许有百分号转义,意味着参数可以有一个 ‘@’ 的前缀,即表示可以从给定的外部文件(或者标准输入)读取字符串或者数字列表。例如 ‘@filename’ 可以被’filename’文件名替代。如果发生这种情况,将不再做进一步的字符串处理。
注意:该文件可以是任何东西,包括可能被程序读取的系统文件和密码文件。作为这种特殊情况下的网站用户应该预先检查输入字符串,或者为保险起见,仍然将该字符串使用 ‘@filename’ 子句上传到IM
如果该字符串不是从文件或者输入流中读取,所有的’\n’字符串都将被’newline’字符取代,任何的’%’的前缀标记都将被替换为适当的值。完整的替代列表见Image Properity Percent Escapes
这意味着越来越多的操作如”-set”,”-sparse-color”, “-distort”, 和 “-morphology”,都可以使用这样的前缀,用户可以基于各种图像属性和元数据来生成参数。
除此之外,你还可以基于图像的内容或者索引来计算不同的参数集,甚至可以提前计算出单个图像或者全部图像的一些复杂设置。
在IM v6.6.9-0 的Percent Escapes和更具体的FX Percent Escapes被图像索引涵括之前,’%p’, ‘%n’, ‘%[fx:t]’ 和 ‘%[fx:n]’等都已经被淘汰了,它们通常只会返回毫无用处的’0’ 或者 ‘1’,而不是图像在图像序列中的真实编号。
延迟处理的百分号转义
在一些设置选项中,百分号转义并不是在命令行中出现的时候就立即扩大,而仅仅是被存储起来。只有当整个文本被使用过,用到百分号转义的图片被发现,字符串中所有的百分号转义才会被扩大,
也就是说这些参数将推迟百分号转义的替代,直至该参数被使用。
这些选项包括如”-label”, “-comment”,”-format”和总体的”-define”值等输入设置。
这也就意味着你可以远早于图像被读取应用指定包含图像特定的百分号转义的”-label”。只有当标签被连接到图像(在图像被读取之后),百分号转义才会扩大,因此可以使用将被应用的图像属性。
影响Percent Escapes更广泛使用的主要局限是目前还只被有限的选项参数使用,比如我们通常不会在 Geometry Arguments中使用,Geometry Arguments同样使用’percent’字符,但是是为了不同的目的。这个问题是IMv7将处理的主要问题之一。
ImageMagick命令
尽管大多数网页中的例子都是用”convert”命令来处理图像,还有很多其它的ImageMagick命令,我将在下文中简单介绍。
其中的某些命令不能在网页中正常的演示,我会给你这些命令的要点和技巧,尽管不能在这里显示其生成的效果。
convert——转换和修改图像
“convert”命令是ImageMagick的主要命令,几乎网页中所有的例子都使用这个命令。因此,我不在这里详述这个命令,而是介绍下这个命令的历史。
这个命令起源于IM初创期,用来转换图片格式,如今还是这个功能,这也就是被称为转换的原因。
这个命令可能都不读取内存中的图像,而是使用IM之外的辅助Delegate 程序直接转换。这种完全外在的形式已经随着时间的推移淡出使用,也较少被需要,除了作为读取和写出复杂的图像文件格式的方式。
在一段时间内,该命令被添加了一些额外的图像处理功能,使这个命令在转换不同甚至是相同的图像格式时,产生了轻微的变化。这些一般是简单的选项,但是在IM的版本5中,这些图像处理功能被扩展了,成为了”convert”命令比进行图像转换更为重要的功能。
因为有各种各样的选项,各种各样的选项在运行的时候,会因为运行顺序的不同而产生各种奇怪而不可控的结果。当多个图像处理选项被使用时,IM因不稳定且不可控而开始失宠。
IM版本6见证了图像处理方式从’options’方式转变为’do it as you see it’方式,图像处理功能变得稳定且可预测,IM的命令行变得有用了多个数量级。
源于此,”convert”再也不是仅仅转换图片格式,而成为了访问图像处理功能的命令行API,如以非常复杂的方式创建和修改图像,而不需要图像处理的学位,或者以计算机语言(如Perl, PHP, 或 C)编程。当然,一些shell脚本的知识是有用的,但也不是严格要求。
identify——打印IM所见图像的详细信息
“identify”命令以简单而有效的方式返回图像的信息。默认情况下,它输出简单的总结,详细说明图像名称、 文件格式、 图像大小、 虚拟画布大小和偏移量、 颜色深度、 内部格式类型,和以人类的角度来看的磁盘中图像的原始大小。
例如:
identify tree.gif
并不是说上面结果中的’8c’不是图像中颜色的数量(在版本6中就不是图像中颜色的数量),而是伪彩色调色板的大小(看之后颜色的实际数量的例子),还要注意图像虚拟画布的大小是实际图像的零偏移,也就意味着很少被使用。
添加-verbose, Operational Control,会生成IM知道的或者容易计算出来的所有信息。包括颜色统计、颜色数、文件信息、图像保存类型等。
IM只是用特殊的”-ping”选项来读取图像的基本信息,这导致识别只尝试读取图像文件的足够信息,而不是整个内存中的图像,来判断简单的图像如大小等信息。大多数的图像文件格式允许该操作,但也有一些不允许。这是”identify”和许多”convert”图像信息输出操作符相比最大的优势。(见 Ping, Operational Control)。
例如:
identify -ping tree.gif
通过”-format”设置和IM特殊的百分号转义生成 Image Properties,可以得到特定的图像信息和特定方式的输出。
For example you can just extract a count of the number of colors within an image.
例如你可以抽取图像中的一些颜色:
identify -format '%k' tree.gif
6
你可以用FX Escape Expressions来进行一些浮点数计算:
identify -ping -format 'double_width=%[fx:w*2] PI=%[fx:atan(1)*4]' tree.gif
这个计算甚至不需要和图像本身联系,你可以在脚本中将IM作为简单的浮点数计算器使用。
关于识别命令的更多介绍
特定的格式细节:
通常在输出使用了识别命令的结果之前,IM会利用各种图像程序APIs和其它辅助程序将图片读取到内存中(本质上是为了本身的内部数据格式)。识别命令会分析所读取或者存储的图像或数据内容,但是不会分析具体的图像格式是如何存储或者处理图像数据。
这是非常重要的,因为可能有识别命令不会汇报的特定的图像格式的特定方面。例如它尽管列出了目前每个GIF图像的颜色表(许多图片都是可能的),它不会指出这个文件中的所有图像是否有相同的颜色表。
如果你需要特定图像文件格式的特定信息,可能使用该图像格式的特定工具会更有效。例如针对GIF文件格式的”giftrans”命令和针对JPEG文件格式的”jpegtrans”命令。
颜色直方图输出:
如果图像中有多于1024种颜色,将没有直方图或者颜色表可以涵盖所有的颜色详细输出。如果一定要得到该信息,可以使用用特殊的’histogram:’文件格式,它包含图像的所有信息。
退出状态:
识别程序如果遇到损坏的图像将返回到一个非零的退出状态,并且将会出现Regard Warnings Control.
error=`identify -regard-warnings image 2>&1 >/dev/null;` if [ $? -eq 0 ]; then echo "The image is good" else echo "The image is corrupt or known format" echo "$error" fi
识别命令的替代——文本输出选项
在IM v6.2.4,你也可以使用特殊的”info:”输出文件格式,从”convert”命令中得到同样的输出结果。
convert ../images/k* \ -format 'image \"%f\" is of size %G' info:
你可以在操作序列的中间用Write Operator写入 “info:”,作为调试工具。更好的方法是用”-identify”选项来写入正常标准输出。
convert ../images/k* \ -format 'Image #%p named \"%f\" is a %m' -identify \ null:
也可以结合”-print”命令来输出其它的信息。
convert null: -print ' (50 + 25)/5 ==> %[fx: (50+25)/5 ]\n' null:
“-identify” 和 “-print”的主要区别在于第一个会应用到内存中所有的图像,但是后者则只运行一次。也就是说我们可以仅仅使用单个ImageMagick命令,就可以生成内存中所有图像的文本文件。
如下,我们生成了再以前的例子中我们使用过的图像的HTML文件。
convert ../images/k* \ -print "<HTML><BODY><CENTER>\n" \ -print "<H1> Display of %n Thumbnails </H1>\n" \ -print "\n" \ -format "<IMG SRC=\"%i\" ALT=\"%f\" WIDTH=%w HEIGHT=%h>\n" -identify \ -print "\n" \ -print "<BR>That's all folks\!\n" \ -print "\n" \ -print "</CENTER></BODY></HTML>\n" \ null:
你可以看到以上的结果展示了将图像输出为HTML Web Page 。
关于这些命令的最后一句话:在默认情况下,它们将显示”convert”命令下的标准输出。除非你重新定义了标准输出,你不能将特定输出转到其它管道或者特殊文件。
利用”info:”来写入输出的要求,可以使你将输出特定到具体的文件,比如图像文件。你也可以将输出特定到预先设定的文件,或者使用特殊的”fd:”输出文件格式。当然,这个一次只能写入一个图像,因此需要一些技巧来安排一次输出。
Mogrify——批量处理
“mogrify”命令在很多方面和”convert”命令很相似,除了它的目的是批量修改图像。”mogrify”命令的初衷是在将图像存储回和图像读取的文件名完全相同的文件之前,批量读取图像(或动画),然后批量修改。因为:
Mogrify是非常危险的,因为它可能轻易的破坏原始图像。
因此,在事情完结前,利用单独的图像的副本来测试”mogrify”。不要再没有备份的原始图像上使用。”mogrify”通常将修改后的图像保存到相同的文件名,但有两个特殊的选项,使之可以将图像保存到不同的文件。
“mogrify”特定的设置”-format”,定义了保存文件时不同的格式和后缀。
例如:
mogrify -format jpg *.png
可以用以上的命令来转换或者批量修改图像,而不损坏原始图像。在这个例子中,将所有的PNG 文件转换为JPEG 文件,用相同的文件名但是不同的后缀。但是值得注意的是现存的同名文件将被覆盖。
因此让我们谨记:
在使用Mogrify命令之前一定要慎重考虑和检查
不然你会发现将你希望保存的东西覆盖掉了,在IM v6.2.0中,你同样可以使用新的”-path”选项为输出的已处理的图像指定不同的存储文件。这个更安全,但是仍然会覆盖在原有的文件中同名的图像。
因此,你可以用如下命令创建一个缩略的子目录。
mkdir thumbnails mogrify -path thumbnails -thumbnail 100x100 *
在IM v6.3.4-3之前,”-format” 和”-path”设置是互斥的。如果你需要适用不同的目录或者不同的图像格式,则需要更新。
由于多图像处理功能,”mogrify”命令不能使用 Multi-Image Sequence Operators或者Image Stack/List Operators。这意味着在”mogrify”命令中,你不能使用诸如”-fx”, “+swap”, “-composite”, “-append”, “-flatten”, 和”-layers”的图像处理操作符
由于许多设置选项需要在第一个图像读取之前设定(如”-size”, “-label” 和 “-density”),这些选项都在第一个图像读取之前处理和设定。在设定之后,每个图像被读取,在处理后的图像被存储和下一个图像被读取之前,操作符按照命令行中的顺序应用到图像。
如果在之后调整了序列中设置,IM会忘记之前的设置。
例如:
mogrify -format gif -size 200x200 -pointsize 18 \ -font Candice -gravity north -annotate 0 "%f" \ -font Ravie -gravity Center -annotate 0 "%f" \ -font Gecko -gravity south -annotate 0 "%f" \ -size 100x64 xc:gold xc:range xc:tomato
你可以看到上述生成的图像的大小取决于第二个”大小”输入设置,第一个较大的设置完全被忽略了。另一方面,”-font”设置是针对每个”-annotate”操作的。
This added complexity means that it is probably a good idea to…
这可能意味着这是一个好主意:
简单地批量处理
不要尝试使用长而复杂的转换,就像使用”mogrify”进行批量操作,可能会有设置问题。如果你实在想进行复杂地处理,那么写一个shell/dos/perl脚本来使用转换命令一次处理一个图像,或者使用ImageMagick API界面。
使用脚本来修改多个图像的示例见Advanced ImageMagick Examples。
记住,”mogrify”是一个非常危险的命令,在实际应用之前,应该在备份图像上测试。
在对大量的图像进行处理之前,我建议在如”mogrify”命令等的脚本中包括一个快速测试,以确保该命令不会损坏任何图像(由于对版本更改或在计算机安装中的差异)。
为保护用户免受不可预见的后果,对大批量图像处理项目而言是一个好主意。我在IM的例子中都会使用,这使我少了很多麻烦。
使用”mogrify”的阿尔法通道
由于”mogrify”不能使用Multi-Image Sequence Operators,它不能轻易地覆盖标志或者是使用Alpha Composition的蒙版图像。
但是有一个例外,即使用”-draw”来实现图像阿尔法通道的合并。在当前图像序列之外,指定第二个图像作为操作参数的一部分。
例如,在这里我首先利用”cp_perl”脚本对希望处理的图像进行复制。然后创建一个临时的圆形的蒙版图像,然后我通常将所有的图像剪成圆形,之后用’Dst_In’ 通道方法是用”mogrify”。
cp_perl 's/^/mogrify_/' eye.gif news.gif storm.gif tree.gif convert -size 32x32 xc:none -draw 'circle 15.5,15.5 15.5,0' circle.gif mogrify -matte -draw 'image Dst_In 0,0 0,0 "circle.gif"' mogrify_*.gif
注意任何阿尔法通道方法可以以这种方式使用,但是只能用恒定的’source’ 或 ‘overlay’应用到所有的图片。
由于”mogrify”将会读取源图像多次,我推荐你使用特殊的IM特定的”MPC:”文件格式来减少在一次又一次读取的过程中图像解码的次数。此图像文件格式不需要被IM解码,而是直接从磁盘映射到内存(和其创建时的机器相同)。这节省了大量的处理时间,尤其是在处理大数量图像的时候。
使用Morgify替代转换
使用 Percent Escapes这一特殊的技巧来修改输出文件名(见Filename Percent Escapes),你可以使用更通用的”convert”命令来替换”mogrify”。
除此之外,它为你提供更多地控制最终的图像文件名。也可以让你更好地进行多图像如成分和动画的处理。
如下,我创建了当前目录的图像的缩图,在输入文件名中插入了一个”_tn”字符串,并创建了合适的输出图片文件名。
convert *.jpg -thumbnail 120x90 \ -set filename:fname '%t_tn' +adjoin '%[filename:fname].gif'
注意,不要在文件名设置时包含不同的文件后缀。当决定使用图像文件格式时,IM不会看见后缀。IM不能从文件名中判断时,它将回落到所读取图像的原始文件格式,所以在使用这个技巧时,一个明确的后缀或者一个编码器前缀非常重要。
利用”%i”,”%d/%f”或 “%d/%t.%e”可以得到源图像所来自的确切的原始文件名。当然在文件名设置中,这些都有IM不会使用的文件名后缀,但是因为有相同的文件格式,在IM中也可以使用。
使用”convert”替代”mogrify”的真正问题是所有的图像都先被读入内存!Mogrify只一次读取/修改/写入一个文件(尽管那个文件可能包含多个图像)。但是”convert”不是这样,因此如果不小心,很容易超出内存限制。但是有解决这个问题的方法。将Read Modifiers和 Thumbnails中的示例。
因为所有的图像都是以单独的图像序列存储在内存中,对于如何处理这些图像需要十分小心。例如你不能直接像往常一样使用 Alpha Composition,但需要使用专门的Multi-Image Layers Composition。
当然,因为原始图像文件可能很容易地被覆盖或者损坏,在”mogrify”这种方法中使用”convert”是非常危险的。
批量处理的另一种方法
如果应用”mogrify”批量处理文件并不实用,尤其是复制而非修改图像时,这时也许一些非IM循环的解决方案可能会更好,这些包括:
# Use a simple shell loop, to process each of the images. mkdir thumbnails for f in *.jpg do convert $f -thumbnail 200x90 thumbnails/$f.gif done # Use find to substitute filenames into a 'convert' command. # This also provides the ability to recurse though directories by removing # the -prune option, as well as doing other file checks (like image type, # or the disk space used by an image). find * -prune -name '*.jpg' \ -exec convert '{}' -thumbnail 200x90 thumbnails/'{}'.gif \; # Use xargs -- with a shell wrapper to put the argument into a variable # This can be combined with either "find" or "ls" to list filenames. ls *.jpg | xargs -n1 sh -c 'convert $0 -thumbnail 200x90 thumbnails/$0.gif' # An alternative method on linux (rather than plain unix) # This does not need a shell to handle the argument. ls *.jpg | xargs -r -I FILE convert FILE -thumbnail 200x90 FILE_thumb.gif
等等。
我建议使用”find”和”xargs”来进行循环甚至非循环文件的处理。关于此的介绍见IM Discussion Post和包含所涉及的危险信息的 Xargs – Wikipedia 指南。
如果你的命令变得比这个还要复杂,则是时候使用shell脚本或者API程序来读取多个图像、收集信息、计算相关参数和处理图像。
我也建议好好看看”parellel”命令(通常用来替换”xargs”),它不仅可以让你同时运行多个命令,还可以轻松地将每个命令在不同的计算机上运行,允许你在处理大数量图片的时候使用分散式处理。
Windows用户,我推荐你看Windows Usage部分,特别是Windows, Batch Processing Several Files。
记住,”mogrify”和其它所有的IM命令会扩展所有包含如’*’ 和 ‘?’等shell元字符的文件名。这样做是为了在老版本的DOS命令行shell中使用这些元字符,然而这可能会导致错误,重复或者一直运行mogrify。一些恶意来源的黑客提供这样的文件名,建议对安全问题谨慎和完全理解。
composite——以特殊的方式叠加图像
“composite”命令是专门用来将两个图像以各种方式连在一起的简单的阿尔法通道合成(叠加)。这包括限制图像结合的区域,虽然使用了第三个蒙版图像。
“composite”命令也提供了简单地访问一些更为复杂的阿尔法通道模式。例如”-dissolve”, “-blend”,和”-watermark”图像合成。如果给定了这些参数,将会覆盖命令中已经或者之后设定的”-compose”设置。
注意”-tile”设置和其他的”convert” 、”montage” 和 “display”的运行都是不一样的。”composite”会导致被叠加的图像平铺在整个背景图像上,这是其它的IM命令不具备的功能。
这些特殊的特征使”composite”成为了一个非常有用的命令,但是现在在”convert”命令中也可以使用阿尔法通道了。(详见Alpha Composition in IM)
将两个或者三个图像叠加的多种不同方式总结见 Layers of Multiple Images中的示例。
关于两个图像合成方法的更多信息见Alpha Compositing中的例子。
The overlay limiting or ‘Masking’ abilities is also detailed in the above examples page in Using a Compose Mask to Limit the Composed Area.
叠加限制和’Masking’功能在Using a Compose Mask to Limit the Composed Area中的例子也有详述。
montage——生成缩略图阵列
特殊的图像批量处理命令”montage”和”convert”一样遵循’do it as you see it’的命令行结构的风格。
唯一不同的是,当命令结束的时候,”montage”将根据当前的设置,将图像序列处理为缩略图索引页。
这使相较于IM版本5而言,”montage”有了更多的功能,你可以像使用”convert”一样对图像进行处理,然后设定”montage”的设置,之后就让它来完成所有的处理任务。
更多关于”montage”的信息见Montage, Arrays of Thumbnails。
display ——图像幻灯片
“display”程序是用幻灯片的形式来展示一个图像或者图像序列。这个命令不是像 “animate”命令一样,对图像进行精心设计和制作计时动画。
每个图像都将显示在和图像大小合适的窗口,除非有其它的选项(如 window “-geometry”,见下)覆盖这个行为。为了展示图像可能有的透明度效果,通常将图像显示在棋盘背景上。
记住这个命令不是用来展示动画的,而是专门为了真实图像的幻灯片展示。因此在在用来显示脚本程序时,应该谨慎。
图像显示时间,循环和其他选项
在默认情况下,除了用户应用 “-delay”设定的延迟,还有 2 秒钟的延迟。然而你可以使用 “-delay 0″选项来使之等待用户输入(空格)。然而默认设置可能被图像本身的设置覆盖,这也取决于文件格式。因此如 GIF 和 MIFF 的动画格式,会导致暂停或者图像元数据延迟设置的延迟时间加 2 秒的延迟。建议你总是根据脚本和需要来设置合适的延迟(记住 “-delay 5×1″将延迟 5+2 即大约 7 秒)。 “-loop”设置是相同的,默认情况下, “display”将永远循环 (“-loop 0”),但是 MIFF 和 GIF等图像格式可能会覆盖默认设置,将在最后一个图像之后退出循环。根据你的情况来设置适当的 “-loop”选项。
注意 “display”不会对 GIF Animation Settings 进行任何处理,因此不会处理帧,虚拟画布大小和偏移量都将被忽略。换句话说,在 中,你将看到 GIF 原始部分图像,而不是完全叠加后的图像。 “-coalesce”选项则正是清理动画来供显示的选项。
透明度处理
包含完整的阿尔法通道( EG PNG 和 MIFF格式)的图像将会被叠加到棋盘背景图像,让用户看到任何半透明如阴影的效果。
可以通过以下的 “-texture”命令选择不同的背景来改变上述情形。
display -texture granite: test.png
display -texture xc:black test.png
有调色板(或布尔值)透明度的图像,如 GIF 和 PNG8 格式,显示了在颜色表中用来表示透明度的当前透明色。这通常使用的是随机颜色(通常黑色)而不是默认的棋盘模式。这可以被认为是一个错误,尽管在技术上看来不是。
但是如果你想像处理其它含有透明度信息的图像一样处理这些图像,则可以在将图像显示之前,利用下面命令改变图像输出格式来删除调色板元数据。
convert image.gif -type truecolormatte miff:- | display -
另外,修改将显示的图像的任何操作也将删除已有的调色板元数据。因此, “display”选项可以用来删除调色板,如利用 “-coalesce”的例子:
display -coalesce image.gif
这可能会额外地清理 GIF 可能存在的动画。但是对多个不相关的图像,它可能会产生不良副作用。
尽管这些方法看起来笨拙,但是确实可以运行。
显示输出尺寸
显示不会缩放图像以适应 X 窗口显示。窗口的大小将会调整来适应每个图像,除非使用了 “-geometry”设置。该设置也可用于修复 X 窗口显示的窗口位置。
即使图像比屏幕还大,图像大小也不会调整,而会溢出屏幕,显示命令会提供一个滚动窗口操作,使用户可以查看完整图像。
在查看现代的高分辨率的数码照片时是非常痛苦的。为了将显示限制在 800×600 的像素区(只会调成更小,而不是更大),使用:
display -resize 800x600\> photo.jpg
对于 JPG 图像,你可以使用特殊的输入尺寸提示设置来加快图像读取速度。见 Reading JPEG Control Options 。
display -define jpeg:size=1600x1200 -thumbnail 800x600\> photo.jpg
如果你想知道你的 X 窗口的显示尺寸可以使用 “xdpyinfo”,尽管这并不是 IM 所特有的。
xdpyinfo | grep dimensions:
注意,你应该使用比返回显示尺寸稍小的尺寸,以使窗口管理器可能在显示窗口进行窗口装饰。
如果图片来源于现代数码相机,你可以利用图像文件格式中的 EXIF 元数据来使用 “-auto-orient”命令更正所显示图像的方向。
如果你不想要菜单,你可以使用 “-immutable”设置 “display”来关闭它,这样它就不会允许被编辑。
显示的脚本使用
考虑到所有这些因素,以下我推荐使用 “display”来显示来自复杂 shell 脚本的结果。
display -delay 0 -loop 1 -coalesce -resize 800x600\> some_random_image
另一种显示方法
另一种显示(而非动画,见之后)的方法是使用更简单的 “x:”输出图像格式(见 display output format)。
convert image.png x:
此方法不提供背景窗口、菜单选项和其他控件。它只是简单地一次显示一个图像。
如果你只是简单地想显示处理后的图像,特殊的 ‘show:’ 和 ‘win:’输出 Spawning Delegate 将和使用 “display”命令对输出图像进行同样的处理及退出。
convert image.png show:
animate ——显示图像的动画
“animate” 和 “display”命令在很多方面都非常相似。
但是 “display”只是显示而非改变给定文件中的图像,在用户输入的每帧之间添加了至少 2 秒的暂停。
而 “animate”则将所存储的任何 GIF Animation Settings应用到图像,且只根据图像的 ‘time delay’ 设置来显示每个图像,从头到尾循环地重复动画操作。换句话说 “animate”命令可以生成动态的图像,而 display 则不可以。
然而,正因如此,第一个图像的虚拟画布大小将控制输出图像的尺寸,另外的图像将覆盖到原来的图像区域。
当然,因为图像是动态的,使用如 “-delay”的选项来对显示时间进行良好的控制。这个命令还有一个参数 “-pause”,在最后一帧的 “-delay”所设定的延迟之外,还会在动画循环的最后添加一个额外的暂停。例如,你可以使用 “animate”来生成两个非常相似图像的 Flicker Comparison ,如下:
convert image1.png image2.png -scale 400% miff:- |\
animate -delay 50 -loop 0 –
我写了一个利用这种叫做 “flicker_cmp”的方法的脚本,发现其在辨别像素强度上的细微变化上非常有用。
compare ——找不同
在 IM 示例的 Image Comparison Page部分有所有当前关于此命令的信息
stream ——对大量图像进行流水线处理
“stream” 是用来在一个大的图像文件中提取一部分图像的专门程序。这是 ImageMagick 中唯一的这样的程序,别的程序在处理图像之前都是完全从内存中读取图像( JPEG 图像使用 “-size”选项时是个例外,因为它的支持库中包含了这个功能。
你可以使用 “-extract”设置来选取部分图像,用 -depth 设置来指定原始数据的颜色深度,还可以使用 “-channel”选项来选择提取的颜色通道。但是 “stream”只根据图像定义的颜色深度输出原始的颜色数据,因此你还需要使用 convert 命令来处理提取出来的输出信息 。
例如:
stream -map rgb -storage-type char -extract 100x100+200+100 logo: - |\ convert -depth 8 -size 100x100 rgb:- stream_wand.gif
更多信息和示例见 Really Massive Image Handling 。
import ——读取屏幕上显示的图像
“import” 命令是一个可以用来从 X 窗口中抓取和提取图像特殊程序。例如可以抓取和打印一个从所有的显示中选择出来的窗口。
import -page A4 -gravity center ps:- | lpr
实际上 “X:”这种特别的文件格式很少使用,它实现的功能和在 convert 命令中时完全一样 。
两者之间的唯一不同是 “import”比 “X:”格式有更多的 X 窗口特定设置,例如指定图像被抓取的显示、屏幕、和 / 或窗口 ID 。
其它选项包括控制显示 ‘beeping’ 和重复快照。如果没有指定具体的窗口,用户可以用鼠标来选取想抓取出来作为图像的部分。
•如果使用鼠标点击,点击整个窗口将抓取和返回一个图像。注意如果显示屏上的其它窗口挡住了所选取窗口的一部分,则将会抓取到被其它窗口遮盖的图像。
•点击根窗口或者选择 “-window root”将会返回整个屏幕。
•如果用鼠标点击并拖动,将返回整个屏幕的 Cropped 部分,也就意味着在显示器(虚拟画布、网页、尺寸)上的位置(虚拟画布便宜)也返回了。
通过使用 X 窗口功能 “xwininfo”,你会发现别的选项可以通过抓取整个屏幕 (“-window root”)、给定窗口标题或者 X 窗口 ID ,来避免人和鼠标之间的人机互动。你也可以使用 “-extract”来减小选定窗口的面积。
将特殊的输入格式 “X:”视为使用 “import”的替代方法:
Note to import from the Windows clipboard use
convert clipboard:myimage image.png
and not “import”
conjure —— IM 试用的脚本语言
IM 试用的脚本语言和多图像列表使用最初是为了 Imagemagick 使用,但是改进的 IM 版本 6 的 “convert”命令见证了这个试用的 API 废用。
它是一种基于 XML 的语言。但如果你想要 XML , SVG 的可能会更好地满足您的需求。
在我看来,在处理多图像序列时,使用 “conjure”脚本也许是更好和更简单。 “conjure”正在被使用,但是由于缺乏示例和用户的支持,使用并不广泛。
图像序列或列表
关于 ImageMagick 需要记住的重要观点,也是使新老用户都混淆的观点,即:
ImageMagick 针对的是整个有序的图像列表,而不是单个图像
也就是说, IM 不仅只处理单张图像,还能将一组图像中的每张单独处理,或者处理图像序列,甚至动态图像中的一系列图像帧。
通常,所有的图像操作符可以应用到序列中的所有图像。
因此,你可以使用 “-draw”操作,它不会像许多新用户所设想的只处理序列中的最后一张图像,而是依次处理当前图像序列中的所有图像。
如 “-coalesce” 和 “-layers”的图像分层操作,将根据序列中的其它图像修改的新图像替换序列中的每个图像。它甚至可能添加或删除额外的图像!
同样地,如 “-append”, “-mosaic”和 “-fx”的图像列表操作,将用合并后的图像替换当前图像序列中的所有图像。这会损坏原来的所有图像,除非使用了 Parenthesis 和 Cloned Images。见下面的 Image Sequence Operators 中的实例。
最后,当读取或添加新的图像时, IM 只会将这个新的图像添加到当前图像序列的末端。实际上,一些格式(比如 GIF )可能会添加多个图像到当前图像序列,除非在输入文件名中添加了特殊的 Indexing Read Modifier来限制读入图像类型。
在保存图像时, IM 将保存在写入时内存中的整个图像序列。在图像格式允许的情况下, IM 将所有图像写入一个文件。如果图像格式不允许多个图像(如 JPEG ), IM 会将图像写入单独的文件(见 Writing a Multi-Image Sequence)
Parenthesis ——按希望的顺序来处理图像
随着命令行选项的形式化,处理的顺序是完全可预测的,并且在图像处理中添加圆括号(或方括号)也成为了可能。这是 IM 用户长期以来都期望的功能,也使用户得以完成在一个单一的命令中不可能完成的操作。
开括号 ‘(‘ 将启动一个所附带的操作都会运行的新的图像序列。闭括号 ‘)’ 则将处理后的图像序列(可能会不止一个图像,或者根本没有图像)添加到原来图像序列的末端。
换句话说,使用 parenthesis 意味着:
“我需要在处理后的结果添加到之前的序列之前,对单独的图像序列进行一些处理”
它让你在添加处理后的结果到主图像序列之外,对一个图像子集进行处理,而不影响你之前已经读取或者处理的图像。
让我们来看一些简单的例子:
convert eye.gif storm.gif -negate +append cmd_negate.gif
正如你所见, “-negate”操作,取消了那时都在图像序列中的两个图像上的颜色。
但是通过添加圆括号,我们可以限制只对第二个图像取消。
convert eye.gif \( storm.gif -negate \) +append cmd_bracket.gif
因为 “storm.gif”被读入了和第一个图像不同的图像序列(通常通过使用 “(“图像序列操作符),你可以在不影响第一个图像的情况下,进行取消。然后我们在像以前将两个图像连接到一起之前,将处理后的结果添加到主图像序列(这就是 “)”操作)。
圆括号必须作为单独的参数给出。也就是说你必须使用空格将圆括号和其它参数分隔开来。不能在周围添加参数。换句话说,在 IM 命令行中, ” \(+clone “是错误的,而 ” \( +clone “则是正确的。
在最后一个例子中,我需要在圆括号前添加一个反斜杠 ‘\’ ,因为在 UNIX (linux) 机器中使用时,圆括号对命令行脚本有着特别的含义。因此在使用的时候,我会避开使用圆括号或者引用方括号。
Windows 的 DOS 脚本并不要求圆括号避开反斜杠。这个和其它 linux 脚本的不同见 Windows DOS Scripts 。
圆括号使之前不可能在单一的 “convert”命令中完成的处理成为了可能,即阵列图像生成。
convert eye.gif news.gif +append \
\( storm.gif tree.gif +append \) -append cmd_array.gif
当然这样的阵列也可以使用 “montage”(见 Montage Concatenation Mode ),但是使用单独的命令使图像处理脚本更为复杂。
当然,如果你想使命令本身看起来更整齐,可以添加额外的圆括号。
convert \( eye.gif news.gif +append \) \ \( storm.gif tree.gif +append \) \ -append cmd_array2.gif
第一组圆括号并不是严格需要的,并在 IM 的内部处理中添加少量的额外工作,但是它通过分离处理步骤使命令究竟做了些什么都很清晰。
括号和设置
选项 ‘settings’ 不会被圆括号影响,而是越过圆括号图像操作,直至设置被更改或者关闭。
例如:
convert -pointsize 24 \ -font Candice label:Outside \ \( label:Inside \ -font Gecko label:Inside \) \ label:Outside -append cmd_settings.gif
注意上述命令中,在括号内时“ -font Candice ”并不是默认字体类型,当在括号外时“ -font Gecko ”也将被默认字体所替代。
换句话说:圆括号只是创建单独的图像序列,并不限制设置,只是限制所处理的图像。
就像 IM v6.4.1-4 ,新的操作控制选项 “-respect-parenthesis”会覆盖这个行为。
如果在 IM 命令的最初设定了这个选项,会导致圆括号保存和检索以前给定的设置。这就意味圆括号内的所有设置,只会保存设置,直到括号结束。
例如:
convert -respect-parenthesis -pointsize 24 \
-font Candice label:Outside \
\( label:Inside \
-font Gecko label:Inside \) \
label:Outside -append cmd_settings2.gif
正如你所见,当括号结束,字体设置会恢复到 ‘Candice’ 字体,替代括号中所设置的 ‘Gecko’ 字体。
这个选项对在短时间内更改大量设置最有用。
convert -respect-parenthesis \
-font Arial label:"This is a line of plain text." \
\( -font Candice -pointsize 16 -fill red -undercolor lightblue \
label:"A line using a lot of different settings." \) \
label:"Text is back to normal -- like Magick\!" \
-append cmd_settings_lots.gif
图像序列操作
IM对图像顺序尤其是对括号内顺序的强调,大量新的图像操作符被用来操纵图像顺序就不足为怪了。
这些操作的参数是索引图像序列的数字,第一个图像为0 (‘0’),第二个图像是1 (‘1′),依次类推。但是如果给定了一个负指数,则将从图像序列的末尾引用。即’-1’是当前图像序列中的最后一个图像(通常是读取或创建的最后一个图像),’-2’则是倒数第二张,依次往下。
-delete {index_range_list}
“-delete”顺序操作符是新的图像序列操作符中最简单的,只是从图像序列中删除一个图像。
convert font_[0-3].gif -delete 1 +append seq_delete.gif
这个操作符的加号形式 “+delete”则不带任何参数,只是删除图像序列中的最后一个图像。
“-delete”操作也进行以逗号分隔的数字列表或者数字范围的图像的删除。
convert font_[0-7].gif -delete 1-4,6 +append seq_delete2.gif
或者删除所有图像(和添加一个新的图像)
convert font_[0-7].gif -delete 0--1 tree.gif seq_delete3.gif
‘0–1’参数意味着删除从第一个图像(index 0)到最后一个图像的所有图像(index -1)。换句话说,也就是当前图像序列中的所有图像。为了避免无图像的类型错误,树图被添加了,使IM显示实际效果。 “NULL:”输出的图像可以使用,但没有结果输出。
如果图像索引不存在,或者超出序号范围, “-delete”将忽略特定文件的删除。
例如,’-25’参数将会删除图像序列中的最后25个图像,但是如果少于25个图像出现,则不会进行任何处理。在这种情况下,你可以使用一个如下的序列来生成一个24个图像的动画:
convert animation.gif new_frame.gif -delete -25 animation_new.gif
但是如果图像的数量是24或者更少,则不会有图像被删除。每次这个命令运行时,图像将增加一帧直至到至少达到24帧。在这之后第一帧将被删除,新的一帧将添加进来。
就像IM v6.3.4中, “-delete”不会删除超出序号范围的图像。
这意味着最后一个例子可以重写如下:
convert long_animation.gif new_frame.gif -delete 0--25 animation_new.gif
这次, “-delete”将会删除从第1个至倒数第25个的所有图像,在图像序列中留下至多24个图像。如果只有24个或者更少的图像,给定的删除图像的范围会被超出,”-delete”操作不会删除任何图像。
-insert {index}
“-insert”在一定程度上是”-delete”的相反操作。它将按照给定的索引,使图像插入至当前图像序列的最后一个位置。
convert font_[0-3].gif tree.gif -insert 1 +append seq_insert.gif
你可以认为插入序号就是你希望在图像序列中插入的那个地方前面的图像个数。
在该索引上的图像(和这个图像之后的所有图像),都会移动至新的索引位置来为新的图像让位。如果使用了一个负的索引值,那么插入的位置就是按被插入图像从序列的最后向前移动来计算的,所以插入的位置看似并不处于原始图像序列中。例如“-insert -2”命令将会调整最后三幅图像的位置,将两张图像放置在新插入的图像和图像序列尾部之间。
convert font_[0-3].gif tree.gif -insert -2 +append seq_insert2.gif
加号形式 “+insert”将把最后的图像移动到图像序列的最前面(index 0),将以一帧有效地移动整个图像。
convert font_[0-3].gif tree.gif +insert +append seq_insert3.gif
可以通过使用 “-duplicate 1来进行以上的相反操作(将一副图像移动到图像序列的末端),0″将复制第一个图像,然后使用”-delete 0″来删除第一个图像。
-swap {index}[,{index}]
使用 “-swap”将交换当前图像序列中两个图像的位置。例如”-swap 0,2″将互换当前图像序列中第一个和第三个图像的位置。
convert font_[0-3].gif -swap 0,2 +append seq_swap.gif
使用这个选项的加号形式 “+swap”将互换当前图像序列中最后两个图像的位置。换句话说,这等同于”-swap -2,-1″。
convert font_[0-3].gif +swap +append seq_swap2.gif
这个操作的最通常的用途是在如 “-composite”, “-flatten”, “-append”,或”-fx”的图像分层操作之前交换两个图像的位置。
convert tree.gif frame.gif +swap \ -gravity center -composite framed_tree.gif
在IM v6.4 中,带有单个数字的 “-swap”将互换最后一个和给定的这个数字的图像,也就是说”-swap 1″等同于”-swap 1,-1″。
convert font_[0-3].gif -swap 1 +append seq_swap3.gif
-reverse
“-reverse”(添加到IM v6.3.4)将简单地颠倒整个图像序列的顺序。
convert font_[0-3].gif -reverse +append seq_reverse.gif
这就是最终的Swap Operator。
-clone {index_range_list}
这个图像序列操作符有一点特殊。在给定的图像序列中, “-clone”将复制由’open bracket’或’parenthesis’操作符保存的图像。
Clone只能在圆括号内使用
这样做的原因是,它允许你从上次保存的图像序列中提取图像的副本,使你在将来进行进一步处理。例如:
convert font_[0-2].gif \( -clone 1 -rotate 90 \) +append seq_clone.gif
使用+clone选项表示只对保存的图像序列中最后一张图片进行复制。
convert font_[0-2].gif \( +clone -flip \) +append seq_clone2.gif
就像版本6.2.2中的, “-clone”操作符将采取逗号分隔的图像列表,或者'{index}-{index}’形式的索引范围。
convert font_[0-2].gif \( -clone 1-2 \) +append seq_clone_range.gif
当然,负的指数将按照你期望的运行。例如,使用数字’0’(第一个图像)和’-1’(最后一个图像),也就是使用范围’0–1’来指定复制整个图像序列。这看起来很奇怪但是有意义也运行的很好。
convert font_[0-2].gif \( -clone 0--1 \) +append seq_clone_all.gif
当你使用逗号来分隔索引序列,图像将按照你指定的顺序提取。
convert font_[0-2].gif \( -clone 2,0,1 \) +append seq_clone_list.gif
如果给定的图像序号范围是颠倒的话(后面的序号比前面的大),那么执行操作时也按照这种反向的顺序进行
convert font_[0-2].gif \( -clone 2-0 \) +append seq_clone_reversed.gif
Clone Image Operator可以不和圆括号一起使用,将从当前图像序列中复制图像,然后直接将图像合并。但是这并不是它本来的用途,也不鼓励使用,因为如果你对这一系列操作添加圆括号,将会产生不同的结果。
同样在上面的例子中,我生成了副本,并且将它们添加到当前图像序列,来演示这个操作符。实际上,我应该使用Duplicate Image Operator 来复制当前图像序列中的图像。你也应该这么做,因为它会让你清晰地看到处理的过程。
MPR:图像存储寄存器,也可以用来复制图片,这在IM v5中也可用。它实际上还是复制和存储整个图像序列供后来使用的有用方法,并且不像上面的图像序列操作符,所处理的不仅仅是单个的图像。
-duplicate {count}[,{index_range}]
你可以使用 “-duplicate”来生成当前图像序列中图像的额外副本(在IM v6.6.8-7中添加),新的图像被添加到图像序列的末端。
不像之前(和老的) Clone Operator,它并不要求使用圆括号。
例如,生成一个图像的N个额外副本(总计N+1个),你可以进行如下操作:
convert font_5.gif -duplicate 4 +append seq_duplicate.gif
如果出现的不止一个图像,则最后一个图像将被复制N次。
convert font_[0-1].gif -duplicate 3 +append seq_dup_n.gif
如果你只想复制最后一个图像一次,你可以使用参数的加形式。
convert font_[0-3].gif +duplicate +append seq_dup_last.gif
如果你想复制一个特定的图像多次,则你可以将图像索引指定为第二个参数。
convert font_[0-2].gif -duplicate 2,0 +append seq_dup_index.gif
这个操作符可以非常快速地生成成百上千的图像,然而直到图像被处理,图像只是简单地复制,共享实际图像的数据。因此,复制的图像记忆力非常强。
参数的索引部分可以包含一系列或一个范围的被复制多次的图像索引。例如复制整个列表两次将生成有原图像数目的三倍。
convert font_[0-4].gif -duplicate 2,0--1 +append seq_dup_list.gif
动画序列的’patrol-cycle’类型也可以用倒序的图像序列生成。
convert font_[0-9].gif -duplicate 1,-2-1 \ -set delay 50 -set dispose previous -loop 0 seq_reverse_anim.gif
注意,我并不复制整个列表,而是跳过第一个(0)和最后一个(-1)图像,生成从-2到1的图像序列。
如果你的IM的版本比v6.6.8-7老,你依然可以使用Clone Image Operator来复制图像,但是一次只生成一系列图像。或者使用本质上是误用Color Morph Operator的技巧来生成多个副本图像。这个技巧就是首先应用一次clone来生成两个完全的图像,然后利用 “-morph”来生成中间的N-2个图像。
convert font_7.gif \( +clone \) -morph 3 +append seq_dup_morph.gif
尽管通过误用 Color Morph Operator,图像也实际上被处理了,因此morph将花费时间来处理图像(不产生变化)。同样的,生成的图像将包含原始数据的副本,内存将存储副本。
结合图像序列操作
使用这些操作符,可以提取特定图像的副本,进行修改,然后将处理后的图片返回到原来的位置。
如下,我对第二个图像进行了 “-clone”,将图像的颜色从颜色改到红色,然后通过首先删除然后插入新图的方式,用修改后的图像替代原来的图像。
convert font_[0-3].gif \( -clone 1 -modulate 100,100,166 \) \ -delete 1 -insert 1 +append seq_update_1.gif
另一种看起来更为常见方法是使用 “-swap”来替换原图像,然后删除在处于末端的图像。这只要你设定两次图像的位置,而不是三次。一次复制,一次替换处理后的图像。
convert font_[0-3].gif \( -clone 2 -modulate 100,100,166 \) \ -swap 2 +delete +append seq_update_2.gif
这些技术将在关于Complex Image Processing and Debugging的下一部分继续讲解。
复杂图像处理和调试
由于 Image Sequence Operators的添加,你不再需要用一步来处理图像,然后每次又保存和重新读取。相反,你现在可以简单地保存在内存中的中间影像,并继续处理。这样可以节省大量的时间,无论是在图像文件格式转换,还是将实际的IO中,将图像保存到较慢的磁盘。
这种类型的图像处理命令可能会非常长且复杂。因此最好是在脚本中写命令,并且尽量将重要的操作符放到一行中,以便编程和处理。见Hints for Better ImageMagick Shell/PHP Scripts。
例如,我通过整个复杂的处理序列在黑色的背景上生成了一个红色按钮。
convert -size 30x30 xc:black -fill white -draw 'circle 15,15 5,15' \ \( +clone -shade 110x90 -normalize -negate +matte \) \ \( +clone -clone -2 -compose Plus -composite \) \ \( -clone 0 -shade 110x50 -normalize +matte \) \ \( +clone -gamma 1,0,0 \) \ \( -clone 2,-1 -compose Multiply -composite \) \ -append seq_process_fx.gif
转换命令的每一行都生成了一个新的图像,除了在最后一行,我将所有的处理后的图像合并到一起来输出最终的处理结果,而不是仅仅最后一个图像。
这种技术让你知道复杂命令的每一步产生了什么效果,以便更简单地调试处理中的每一步。
注意如何只使用初始图像的大小和形状生成按钮的初始形态,所以你可以自由使用你喜欢的任何形状或图像!该命令的其余部分将像以前一样处理它。
当然,你通常会删除所有的临时处理图像。我将用类似如下的命令来替换上面的最后一行:
-delete 0--2 seq_process_result.gif
其它的检查结果的方法是将结果送到显示命令,以在屏幕上查看结果,而不是将它保存至图像文件。也就是在最后一行使用如下的命令:
+append miff:- | display -
除了使用 “display”,你也可以使用’show:’。将在屏幕上显示处理后的图像,然后允许最后的命令继续或者退出。更多信息见Show, Display Image Output。
+append show:
通过’spacebar’,IM将显示序列中的每一个图像,这种情况下,不需要使用 “+append”。
你甚至可以使用更花哨的 “montage”命令以更好的方式查看结果。
miff:- | montage - -bordercolor blue -border 1 -geometry +2+2 show:
这种类型的图像处理还允许一旦图像被创建,就可以方便地看到中间图像。可以在between “\( … \)”语句中加入如下的命令行:
\( +clone -write show: +delete \)\
一旦中间图像被输出供显示,IM就会自动继续处理。见 Show, Display Image Output。
插入如下的命令,你可以显示在那个时点所生成的所有图像。
\( -clone 0--1 -append -write show: +delete \)\
在图像处理步骤调试和解决之后,你可以优化代码,这样你可以使用较少的括号步骤和 Cloned Images,最后删除的中间图像也会较少。
“Image Composition”和”Layer Flattening”都是将多个图像合并到一起,最后留下一个处理后的图像,减少内存中中间图像的数量。
convert -font Ravie -pointsize 48 -background black -fill white \ label:'IM' -bordercolor black -border 5 seq_label.gif convert seq_label.gif +matte \ \( +clone -shade 110x90 -normalize -negate \ +clone -compose Plus -composite \) \ \( -clone 0 -shade 110x50 -normalize -gamma 1,0,0 -matte \) \ -delete 0 +swap -compose Multiply -composite seq_button.gif
ImageMagick以一种标准的程序化和自动的方式,在单个命令中使用多个步骤,使IM成为了强大的工具。你写一个复杂操作的脚本,然后将它使用到许多图像。图像序列操作符和括号使IM更为强大,使你可以用少量的命令写出更复杂的图像处理程序。
另外的一个复杂图像处理的脚本示例见Scripted 3-D bullets from Shapes。
改进图像处理脚本,使之更容易编辑和理解及别人可以了解你做了什么的方式见Hints for Better ImageMagick Shell/PHP Scripts。
图像元数据
到目前为止,我们已经看了组成图像的实际内容和数据。但是图像不仅仅是图像数据。还有也是图像一部分的属性和元数据,影响图像处理和其它程序如何处理图像。
例如图像应该有一个’offset’或者成为一个大的虚拟画布的一部分。也就是说一个单独的图像可能是由一系列其它图像组成的大的图像中的一小部分,来构成图层或动画。
IM也有很多被许多图像处理操作符用来修改如何运行的特殊设置。例如,使用背景颜色。其中一些是全局设置,对整个图像序列中的图像进行相同处理,还有一些在图像之间是不一样的。
还有哪些是图像中的一部分呢?
图像元数据通常(但不是总是)以图像文件格式存储在图像中。比如,配置文件、标签、标题、评论和虚拟画布信息。这些都是单个图像设置,当前图像序列中的图像的设置可以是不一样的。
全局设置被许多不同的图像处理操作符使用,但是通常不保存在图像中。包括背景色、边框颜色、填充、mattecolor、字体、点、重力、构成方法、颜色通道处理、读/写入色彩深度值等。
专业的设置和定义,用于特定图像处理操作符更深的低级别处理。比如失真视图、特殊组成方法参数。
图像实际上是如何存储在ImageMagick的内存中的:如以RGB或CMYK的形式,不管在读取的时候,阿尔法通道是否呈现与启动,图像的调色板是否存在。然而在编译时,许多存储设置都难以解码。
一些一般的IM操作性设置,如调试或详细设置,通常控制信息输出或者错误处理。
也就是大量的信息可以被存储,和/或影响图像的处理。当它们被分成许多组,如果设置是全局的,指定了图像,ImageMagick如何处理图像,很大程度上取决于所涉及的特定操作。
我也很模糊,在你明确之前很难不觉得模糊,它也是非常容易令人困惑的。
所有这些值以三种不同的方式存储在内存图像中。
属性:
这些都以特殊的数据结构存储,通常用来允许各种图像处理操作能快速和直接地访问。比如:图像大小、虚拟画布的几何形状、背景、填充、描边、matte colors、点、密度、字体、构图、插入、虚拟像素方法、配置文件块、时间延迟和处理时间等等。
请注意,其中有些是“具体”到每个图像的的,但有的则是作为一个“全局性”的设置, 通过CLI界面,以相同的值对所有图像,即使它们是以每个单独图像的一部分存储。
作为图像处理中的一部分,属性一般通过许多选项修改,或者更常见的是使用Set。
性能:
根据个人意愿,自由形式的键值字符串附加在每个图像上,每个图像可以有完全不同的字符串。本质上,他们都不需要定期访问或解码,或者以特殊方式是用。
比如:标签、标题、注释字符串;创建和修改日期;用户定义的字符串;一些操作的结果。
用户可以用Set来设置或更改,只要’key’不对应已知的’attribute’。
Artifacts:
这是针对所有图像的一个自由字符串全局设置。
它用来控制自由形式的全局设置来定义或修改所有图像的读取和修改。有关 “verbose”设置导致一些操作输出处理过程的信息的例子,包括更详细的识别输出。
用户可以用Define 或者Set的特殊用法(见Using Set “Option:” to Define and Artifact)来修改全局设置。
了解这三个存储方法是理解ImageMagick中设置和元数据处理是如何运行的,允许你进行一些高级和比较困难的图像处理。
设置/更改图像属性
简单元数据通常是图像处理中最重要的图像属性。
这样的数据通常以两种方式修改:当图像被读取时,直接改变图像元数据;或者当图像在内存中创建时就对元数据进行修改。
例如, “-label ‘string'”设置被设定之后,将在每个被读取或者创建的图像上进行注释。但是”-set label ‘string'”将改变当前图像序列中所有图像的标签元数据。
两种方法的原因是历史的后向兼容性和方便性, “-label”通常在所应用的图像被读取之前设置,但只是影响设置之后读取的图像。
例如:
convert -label one image_one.png \ -label two image_two.png output_image_list
“-set”操作符改变当前图像序列中包含之前所读取的所有图像,因此,一般要用圆括号来限制哪些图像你将应用该操作。
convert \( image_one.png -set label one \) \ \( image_two.png -set label two \) output_image_list
你可以使用 “+label”来取消设置,在这种情况下,在图像被读取或创建时只留下元数据。如果被读取的图像如果没有标签,IM将返回到逻辑上的默认设置。对于标签,这只是空字符串。
你可以看到更为详细和具体的使用两种方法的例子, Montage Labeling of Images 就大量使用标签功能。
这个想法同样适用于在输入时设置图像元数据的其它选项。包括: “-comment”, “-caption”, “-page”, “-dispose”, “-delay”。
虚拟画布大小和图像偏移设置也有一个特殊的操作 “-repage”(见Page and Repage)
例如,我使用所有可用的设置方法来设置单个图像的虚拟画布偏移量和也,就像我创建了它们的一个动画序列。
convert -delay 100 -dispose Background \ -page 100x100+5+10 eye.gif \ -page +35+30 news.gif \ \( storm.gif -set page +62+50 \) \ \( tree.gif -repage +10+55 \) \ -loop 0 animation_page.gif
你会发现从单独图像文件创建多个图像序列时,使用传统的方法更简单。但是放你需要改变已经读取到内存或者从图像处理中创建的图像时, “-set”或者更专业的”-repage”操作符会更好。
例如,要改变在最后一个例子中第三个图像的图像偏移:
convert animation_page.gif \ \( -clone 2 -set page +55+10 \) -swap 2 +delete \ animation_mod.gif
在一个图像序列中提取和修改单独的图像的更极端的例子,见Frame by Frame Modification of an Animation。
以下是使用 “-set”来对所有图像进行注释,然后修改特定的图像。
convert xc: -duplicate 9 \ -set comment 'T minus %[fx:n-t]' \ \( -clone 7 -set comment 'We have ignition!' \) -swap 7 +delete \ -format "image #%p : %c" info:
你可以使用 “mpr:”作为对内存中的图像设置属性的另一种方式。例如我们可以取出一个带有’Bad’评论的图像,用’Good’来替换评论。
convert -comment 'Bad Comment' rose: \ \ -write mpr:register +delete \ -comment Good mpr:register rose.jpg identify -format "image comment = %c" rose.jpg
这个可以运行,但是使用起来非常笨拙和痛苦,特别是当处理多个图像如动画时。实际上,这是更改IM 版本5中修改元数据的唯一方式。
一般的全局属性
建设中
这些属性中的大多数通常都在图像读取到内存的前后进行全局性设置。它们通常被用来作为以后图像处理操作的一般控制。
*许多设置只是按照需要全部保存:
-fill -background -bordercolor -strokecolor -mattecolor -quantize
+dither -channels -size -gravity -units -density -font -pointsize
-tile
*有些设置会影响图像保存到磁盘的方式和图像中保存的元数据,这些包括:
-loop -compression -quality -depth
-density -background
* -compose非常尴尬,因为它只能进行全局设置。但是,如果取消设置,每个图像可以有不同的的设置(分层)。
这些中的绝大多数都可以被关闭(使用+ version),将导致操作返回图像元数据中的设置。(例如:+background将返回原始图像的元数据)
但是通常情况下,它将返回一些默认值。例如,+gravity返回’None’或者无重力。
当写入时,少部分也将和图像一起保存。尤其是GIF格式将把-background和-bordercolor作为图像属性的一部分保存,但是这些通常会被读取这些图像的程序忽略。
你会注意到许多设置在多个地方使用,例如-density。
*在读取许多矢量格式如Postscript, PDF, 和 WMF图像格式时使用。
*同样用于特殊的图像操作符如label: caption: 和 text:
*作为-annotate -draw 和 –polaroid操作符中字体的一部分使用。
* 最后,一些格式存储作为图像文件格式一部分的密度和分辨率。
设置会如此令人困惑的原因也就在此。
Page、Repage和虚拟画布
IM中’page’或者’virtual canvas’设置的主要目的是定义如何在一个大的画布上放置一个图像的真实部分(包含颜色数据的部分)。在 Layers of Multiple Images和GIF Animations中,涉及到多个图像且需要根据相对位置来放置图像 时这尤为重要。
在Postscript和在Text的’page’中生成图像时,它也用来定义在一个大的纸或者’page’中图像放置的位置。
它最经常用于Layers of Multiple Images 和 GIF Animations,也在Cropping和 Trimming 图像时,用于记住图像的原位置。
现在,’page’定义了两个不同的部分:一个虚拟画布或区域,定义了图像存在的更大的区域和真实图像在画布中的位置及偏移量。
当出现负的偏移量时,画布的区域局限于从0,0到给定的宽度和高度。指定的还是一个正的大小的画布。
大小和偏移这两方面是紧密相连的,但是通常分开处理,或者以更能控制的方式。所以除了常规的 “-page” 和 “-set page”方法,一个单独的选项”-repage”也被用来进行更好的控制。
具体来看:
+repage
没有参数,将根据真实图像重置虚拟画布。这将清除图像虚拟画布所有的信息。
这通常在使用Cropping和 Trimming等图像sub-diving操作符之后使用。
这在将图像保存到GIF或者PNG图像格式之前,删除虚拟画布尺寸和偏移量时尤其有用,因为许多浏览器将画布和偏移量信息作为图像的一部分进行显示。
-repage WxH
更改现有图像的虚拟画布的大小,但不重置图像在画布上的位置。
注意将这个参数用到 “-page”或 “-set page”将重置图像的位置至可能并不想要的’+0+0’。
-repage +X+Y
只是将画布上的图像移动到这个绝对位置,但是不改变图像画布的大小。
-repage +X+Y\!
按照所添加的给定数字,相对于现有图像位置来移动画布上的图像。
-repage 0x0
试图找到可容纳整个图像的最佳虚拟画布尺寸。
这可能对有着负的偏移的图像无效因为没有办法可以指定一个负数的虚拟画布。为避免这个问题,将使用实际图像的尺寸作为画布的最小尺寸。也就是它从来不会指定一个零尺寸的虚拟画布。
-repage 0x0+X+Y
移动图像的偏移量,然后重新指定虚拟画布的大小来适合图像的新位置。
-repage 0x0+0+0
等同于 “+repage” 或”+set page” 或 “-set page 0x0″。所有的虚拟画布和偏移信息都取消了。
-repage WxH+X+Y
等同于 “-set page WxH+X+Y”,也就是直接指定值。
注意使用’!“标志将给定对图像当前偏移进行抵消的相对偏移量。也就是说,’-repage +5+0\! “将向右移动5个像素的偏移量,而不修改虚拟画布的尺寸。
在给定负的偏移位置时一定要谨慎,因为GIF文件格式并不处理这个,而是将其重置至零。当在PNG图像上使用负的偏移时,一些浏览器不能正常显示。哪些虚拟画布的信息会被保存在图像中依赖于图像格式。
JPEG 和许多图像文件格式,JPEG图像根本不存储虚拟画布信息,信息将被忽略和丢失。
GIF 虚拟画布的尺寸和偏移量将会作为GIF动画处理的一部分保存。但是它不处理负偏移量,任何负的设置在保存时会重置为零。
PNG 偏移量甚至是负的偏移量都会被保存,但是PNG文件格式通常不会保存虚拟画布信息。但是由IM保存的PNG图像将包含虚拟画布信息,但是只会被其它的IM命令应用。
如果IM读取的PNG图像没有这个特定的属性,它将设置图像虚拟画布到合适的尺寸使图像在虚拟画布上可见(如 “-repage 0x0″)。对于没有偏移的图像,虚拟画布和实际图像的大小是一样的。
GIF和PNG等格式将保存虚拟画布信息,但是其它如JPEG的图像格式则不会。所有这些格式对虚拟画布信息都有各自的限制,只有内部MIFF文件格式没有这些限制。
注意对 “text:” 和 “ps:”图像生成操作符有特殊的含义(见Text: Multi-line Text Files 和 PS: Postscript formatted Text and Graphics)。正常画布大小和偏移的信息在创建图像的时候并不使用。
设置和每个图像属性
不仅仅是因为用户经常喜欢添加或定义他们自己的设置, IM也不会进行一个图像可有的所有可能设置的操作,这也是不可能的。
正因此, “-set”选项以任何值定义任何设置。
如果给定的值对ImageMagick是未知的,它将作为一个’Property’存储在图像中,将被列在详细 “identify”输出的底端,或者返回或利用Percent Escapes扩大。
例如,在玫瑰图像的创建中,自动生成了三个’properties’:两个日期字符串和一个’signature hash’。我也添加了我自己定义的’property’设置。
convert rose: -set my_property my_value -verbose info: |\ sed -n '/Artifacts/q; /Properties/,$ p'
一些图像处理操作符甚至返回作为图像’properties’的特殊值。例如由Best Fit Label选定的最终点将作为特殊的图像property存储。
convert -size 100x label:Anthony -verbose -identify property_label.gif |\ sed -n '/Artifacts/q; /Properties/,$ p'
注意 label:操作符,它本身也设置了’label’属性,碰巧被存储为property字符串。
所有的’properties’都是以自由字符串数据类型保存,以图像元数据存储。
因此,不是所有的属性都存储为’properties’,许多属性需要以数值数据存储和直接使用。一个例子是虚拟画布的’page’属性。
在这里我使用了确定的 “-format”设置使IM输出在内部创建的标签的点。
convert -size 100x label:Anthony \ -format 'pointsize = %[label:pointsize]pts' info:
使用这个信息来生成新的标签图像是一个技巧,将在下面看到。
“filename:”设置是你可以用的最有用的用户定义的设置。例如:
convert rose: -set filename:my_area '%wx%h' 'rose-%[filename:my_area].png'
以上将生成一个命名为 “rose-70×46.png”的图像。
尽管任何名字都可以使用,作为一项安全措施,只有有用户定义的设置前缀的 “filename:”字符串才可以在文件内外使用。更多示例见Filename Percent Escapes。
定义和全局Artifacts
定义的值被认为是’Artifacts’和对所有图像中进行全局设置及都通过特殊的”-define”操作符设置。
这样的’Artifacts’的主要目的是作为可以图像文件格式编码器和图像处理操作符的额外设置使用。它允许为特定要求的自由形式设置的添加,而不需要创建另外的属性。
作为全局设置,它们并不附属于特定图像,而是附属于图像序列中的所有图像,当新的图像被读取或创建时可用。
注意API’s可以有附加了不同系列’artifacts’的多个图像序列,但是CLI只有一个积极图像序列,因此’artifacts’都是全局的。
换句话说,’defined artifacts’为专业用户提供了一种在常规参数用法之外,修改特定操作符的常规和标准操作。例如,读取和写入这些图像的JPEG Coder Settings。
-define jpeg:size=300x200 -define jpeg:preserve-settings=1 -define jpeg:ptimize-coding=true
Image Distortion Options, 例如:
-define distort:scale=2 -define distort:viewport=44x44+15+0
Resize Filter Controls, 例如:
-define filter:blur=0.75 -define filter:support=1.25
一些人工定义有捷径,因为它们经常被用户使用。
例如,”-verbose”选项控制(见下),等同于使用”-define verbose”,因此创建了一个’verbose’产出。例如:
convert xc: -verbose info: |\ sed -n '/Tainted:/q; /Artifacts:/,$ p'
接下来,加形式”+verbose”删除’verbose’产出,因此等同于”+define verbose”。
Artifacts和延迟百分号转义
Artifacts也经常在定义被给定之后,用来保持分配到所读取图像中的特殊属性。
“-label”设置也只是设定由用户提供的参数的Artifacts,在新的图像被读取或创建之后,这个Artifacts被转换为’label’ Setting or Propriety
例如用标签设置创建一朵玫瑰图像。
convert -label "%wx%h" rose: -verbose info: |\ sed -n '/Tainted:/q; /Properties:/,$ p'
也就是说”-label”首先定义了’label’显示的产出,当玫瑰图像被创建之后,IM将全部的artifact转换为图像特定的’property’,就在那个时候才扩大Percent Escapes,这被称为Delayed Percent Escapes。
由于Delayed Percent Escapeis,”-define”仅仅保存字符串,而”-set”操作符则进行扩大。
使用设置“option:”来定义Artifacts
我们在上面显示了你如何在单个图像上”-set”特定目的的Proprieties。例如:
convert -size 80x40 xc: -set myinfo 'I love IM!' \ -gravity center -annotate 0x0 '%[myinfo]' \ property_annotate.gif
但是因为Proprieties附属于特定图像,不可以在新图像的创建中使用。例如这会失败:
convert rose: -set myinfo 'I love IM!' label:'== %[myinfo] ==' \ -gravity center -append properity_append_fail.gif
如你看到的,’myinfo’ properity建立于或包含于附加标签中。
另一方面,全局定义的Artifacts 对图像操作符是可用的,也必须可用以便图像生成器或图像文件解码器读取它们来进行各种控件设置。只要使用”-define”,将按照预期运行。
convert rose: -define myinfo='I love IM!' label:'== %[myinfo] ==' \ -gravity center -append artifact_append.gif
那么怎样才能使用图像的特性或属性来创建一个标签?”-define”选项当前还不允许图像特性的使用!
技巧是在使用”-set”选项时使用特殊的前缀”option:”。这个添加导致”-set”定义一个遵循前缀的名称的’artifact’。例如,这相当于最后一个例子:
convert rose: -set option:myinfo 'I love IM!' label:'== %[myinfo] ==' \ -gravity center -append properity_option_append.gif
最重要的是,”-set” 选项将扩大 Percent Escapes, 也就意味着如果我们有一些单个图像 Propriety,我们就可以将它转换为全局的Artifact。例如,我们可以创建一个标签,然后将由图像生成器创建的”label:”的’label:pointsize’特性转换为全局产出’my_pointsize’。作为人工产出,当创建第二个标签图像时,这些信息是可得的。我将两个标签合并到一起(使用单独的’gray’命令行)。一个非常技巧性的例子。
convert -size 100x -gravity center label:Anthony \ -set option:my_pointsize '%[label:pointsize]' \ -set option:my_height '%h' \ -size 100x1 xc:gray \ -size 100x label:'at %[my_pointsize]pt and %[my_height]px high' \ -append property_append.gif
注意上面”-set option:…”的替换。如果你是将它在”xc:gray”创建之后放置,它将用来设置全局产出。这是因为只有最后一个图像的特性定义全局产出中存储的值。
其实真正发生的是,”-set”被用于当前图像序列中的每个图像,即使产生全局产出。因此,每个图像将会把自己的特性指定到全局产出中,取代原来设定的值,完成之后,只有最后一个图像定义产出。
这时,’FX escape’不能读取特性或属性,你也不可以对这些值进行计算。
读取和写入时的图像类型
当一个图像被读取或写出的时候,”-type”操作符/设置定义了将使用的类型或者色彩空间,来确保结果图像(在内存或者图像文件中)是你所期望的。作为这个的一部分,可以在文件输入或输出的时候,进行一些Color Space 修改,尽管只是用来保证图像是所期望的形式。
例如,”-type”有一个特殊的’bilevel’设置,可以以相同的图像格式转换和保存有两种颜色的单色图像的影像。类似的,’TrueColor’和 ‘TrueColorMatte’可以用来促使TIFF 图像以全彩RGB保存,即使图像是纯粹的灰度图像。
其它的设置包括保证写入的图像是灰阶的’GrayScale’ 和 ‘GrayScaleMatte’。或者’Palette’以支持这个选项的格式来强制使用索引颜色图。
读取图像文件格式时,’TrueColorMatte’的”-type”设置将促使JPEG 图像被读取,在内存中添加’Matte’ 或 ‘Alpha’通道,即使JPEG格式本身也不能处理透明度。
当写入 PNG文件格式时,设置一个’Pallette’的”-type”,将强制使用颜色索引” NG8’内部文件格式。类似的,使用”BiLevel”将强制IM使颜色图像抖动为黑色和白色来适用于大多数文件格式。
但是”-type”的准确含义和功能取决于你读取或者写入的特定文件格式。见各种 Image File Formats示例,特定PNG示例见PNG output formats。
控制图像质量
深度(Depth)——文件格式的位深度
质量和深度是两个经常在邮件列表和例子网页中提到的术语,因此,我在这儿稍微介绍下。质量是ImageMagick中一个编译时的设置,用来决定在IM内存和图像处理过程中存储图像的值的大小。从本质上来看,也就是特定的IM编译的处理质量。
深度是从文件格式中读取或者保存到文件格式中时所用的值的大小。它充满变数,由”-depth”设置或者由所读取图像的原始深度控制,
记住:
质量是在内存中值的大小,汇编到IM中。
深度则是文件格式值的大小,是可变的。
现在大多数图像格式的深度都为8,也就是说用8位(或者是从0到28-1的值)来保存图像中用到的每种颜色值。0到255中的一个值为红色,0到255中的一个值为绿色,0到255中的一个值为蓝色通道。更经常的是这种图像类型被叫做24位图(也就是”bits perpixel”,而不是像由”-depth”设置使用的”bits per value”)。这也包括这样的图像格式:JPEG或者如果有阿尔法通道的32位/像素图,和典型的PNG 图像。
大多数指的是8位图(8位/像素),是有8位调色板或颜色表的真实图像。实际的像素数据是之后用来从颜色表中查询像素颜色的8位索引(0-255)。这是’raster’(像素阵列)只是用来从一个单独的表中查找实际的像素的颜色的索引。
换句话说,尽管8位图像有8位深度,只是一个索引,而不是真实颜色。这种情况下的值指的是用来存储真实像素数据的位的数目,单个的8位置常常用来从颜色表中查询颜色。GIF图像是这种情况的一个例子。
这种图像中的透明度要么通过指定一个代表透明度的颜色(就像在GIF格式中)来处理,要么像在 PNG8 图像中,使用一个有特定颜色数目的
一般说来:
24位的图像是:3× 8位值 – 3个颜色通道
32位的图像是:4 × 8位值 – 3种颜色+ 阿尔法通道
8位的图像是:有256色的限制的8位色彩索引图像
因为大多数的图像格式只以8位深度保存颜色值,许多人安装的IM使用一个深度8的’Q’ 或质量水平,相较于IM的Q16版本而言,这要求更小的内存,处理图像也更快速。Q8版本在通常的图像处理和转换中都运行的很好,可以用来生成简单图像、注释或图像叠加。
但是虽然低质量的IM运行更快,也更节省内存,在使用包含多个颜色变化、变暗、发光、伽马或直方图颜色校正等的操作的复杂序列时,它不能正常运行。在Q8中,内存中的中间图像也会以8位质量保存,因此多个操作中的每个操作都会导致越来越严重的失真。结果可能会严重地受位水平四舍五入的影响,特别是在极端的接近白色和黑色的颜色。(见下)
质量(Quality)——内存位质量
记住:质量是ImageMagick中的一个汇编时的设置,用来决定在IM内存中和图像处理过程中存储图像的值的大小。它不能被改变,除了从源代码重新编译ImageMagick。
‘Q16′ 的ImageMagick(默认情况下)将使用’Q8’版本至少两倍的内存,并且取决于你的CPU,慢了许多,尽管在今天的处理中这是不太可能的。同样,你可以编译“Q32”和“Q64”的版本,虽然这些都不是很常见的,通常只在非常高端的图像处理中使用。新的HDRI的编译质量见下。
一个“Q16”的ImageMagick也可以让你保存每个像素值的更多的位信息,也就是说颜色值是以从’0’ 到 ‘2^quality-1’的范围内的整数值保存。这最后的一个值在IM程序中被称为当前的’QuantumRange’(或老的绝对名字’MaxRGB’)。
质量设置越高,在编制IM时使用时,用来将图像存储在内存中的颜色值越精确。这意味着,如果你在处理图像时生成了一些非常小的、轻微的颜色的变化,这些变化将保存在ImageMagick的内存中,而且在以后的处理过程中不会丢失。
噪声滤波器,模糊,锐化,平均,全局色彩,伽马,和直方图修改,或大量复杂的构图等操作,在Q8 IM中都可能产生不必要的颜色错误,在处理后的图像上生成非常明显的色彩产出。
当然,将最终的图像保存到8位质量图像格式将’quantize’这些颜色值回到8位,在图像处理过程中,质量被保留。
一些格式可以用来保存由IM使用的更高质量水平的信息,例如MIFFIM格式,列举了像素的TXT格式,也包括 NetPBM 图像格式。
但是在Q8版本的IM,它将会使你输出一个16位深度图像,这样的图像将仍然只有相当于8位深度的信息,因为这样的图像是不存在的。
如果IM读取了一个8位质量的图像格式的图像,图像的“深度”将设置为8位,且IM通常以8位深度保存图像,会保存在8位深度的图像,即使你使用Q16版本的IM处理图像。你可以用”-depth”设置覆盖这些。
并且,如Image Resizing 等生成额外颜色的操作符,将根据汇编时的质量设置重置内存中图像的深度,因此IM将以一个更高的深度保存它。
HDRI——浮点数质量
HDRI,或者叫High Dynamic Range Imaging,初衷是用来更自然地展现我们的眼睛同时看见一个屏幕的亮和暗的部分。在实际的图像处理中,它的功能远多于此。
IM的HDRI的版本是专门编译来为内存中存储的图像使用浮点数,让你能够精确的HDRI图像处理,用于防止的在极端’clipping’图像色彩。
HDRI仍然使用相同的颜色范围作为默认的编译时的Quality Setting 。也就是说值从’0’到 ‘Quantum Range’意味着从黑到白。但是值是以浮点数而不是整数保存,因此取整的’quantum’效应不会出现。当值超过了’Quantum Range’或变为负值,值不会’clipped’。
当你计划使用极其复杂的数学处理图像,包括负值的临时使用,或强烈的缩放到很小或非常大的价值时,HDRI至关重要。对于想充分利用新的Fast Fourier Transforms (FFT)功能尤其重要。在这里,你将看到IM版本的HDRI版本的大多数例子。
编译IM的HDRI版本的信息见IM网页上的Enabling HDRI in ImageMagick,关于Windows 和 Ubuntu Linux specific的信息见用户论坛上的 Fourier Transforms Announcement Discussion。
在使用HDRI时,一个需要牢记在心的重要操作符是”-clamp”。这个选项将修改下降到图像的正常范围之外的图像的值。也就是说负值将修改为0,任何大于’QuantumRange’的值将被设置为那个值。但是它并不四舍五入浮点值至整数。
量子效应,HDRI vs non-HDRI
量子四舍五入
例如,在这里我使用了 Level 和 Reverse Level操作符,压缩渐变图像的颜色范围,所以它们只使用从0到15的值,然后再解压缩。由此产生的梯度也显示为图像配置文件(使用”im_profile”脚本)来使之更容易遵循。
# Using a normal non-HDRI version of IM... convert -size 20x600 gradient: -rotate 90 \ +level 0,15 -level 0,15 level_rounding.png im_profile -s level_rounding.png level_rounding_pf.gif
注意四舍五入(量子效应)的服务器现在是可见的,形成了渐变图像配置文件的步骤。因为只使用了16个灰度值,你可以有效地将图像转换为只有4位图像深度。
这种四舍五入问题的类型在IM Q8版本中非常常见,除了基本的调整大小、裁剪图像,还包括进行多个图像处理任务等。
当你使用大量的图像处理,比如Fast Fourier Transforms (FFT) 或合并不同有着不同曝光时间的图像来生成High Dynamic Range Images时,四舍五入只会成为IM Q16的问题。这就是为什么HDRI终究是第一个添加到ImageMagick中的。
Burning 和 Clipping…
在再次保存之前延伸渐变范围,因此最初的黑色和白色值将会超出量子范围。
# Using a normal non-HDRI version of IM... convert -size 20x600 gradient: -rotate 90 \ -level 20% +level 20% level_clipping.png im_profile -s level_clipping.png level_clipping_pf.gif
常规的IM将丢失两端的信息,低端的值将被’burned’变为负值,而较高的值则当其超出用来存储值的最大’Quantum Range’整数限制时被截尾。
HDRI version of ImageMagick result…
ImageMagick 的HDRI版本导致:
使用HDRI版本的ImageMagick重复这两个操作,不会产生上述的任何凑整、burning、或对结果截尾,但是会占据额外的内存。由于浮点加速器,运行速度快,并不占据大的内存。
# Using HDRI version of IM... convert -size 20x600 gradient: -rotate 90 \ +level 0,15 -level 0,15 level_rounding_hdri.png convert -size 20x600 gradient: -rotate 90 \ -level 20% +level 20% level_clipping_hdri.png im_profile -s level_rounding_hdri.png level_rounding_hdri_pf.gif im_profile -s level_clipping_hdri.png level_clipping_hdri_pf.gif
你可以看到渐变的保持完好,即使对图像进行压缩和伸展,然后再返回。
在HDRI中使用Clamp来限制图像边界
你可以通过使用在连个水平选项之间的”-clamp”,强制HDRI图像被正常图像值范围’clipped’。
# Using a HDRI version of IM... convert -size 20x600 gradient: -rotate 90 \ -level 20% -clamp +level 20% level_hdri_clamp.png im_profile -s level_hdri_clamp.png level_hdri_clamp_pf.gif
使用上面的”-clamp”,生成了和使用正常的ImageMagick非HDRI版本一样的图像。
但是这个图像不会和非HDRI中的结果一直,因为”-clamp”将会对图像的值burn和截尾,它不会添加量子四舍五入影响。因此,在最后的保存至非HDRI图像文件格式是不会被取整。
在使用HDRI达到你想要的结果时,”-clamp”选项非常重要。
HDRI文件格式
当然,因为相同的原因,将一个包含很小、很大或负值的图像保存为正常的图像格式时,也将被剪辑、量化、甚至被减少颜色,因此,如果要保存没有被标准化为0到’Quantum Range’标度的图像时,需要使用一个罕见的浮点图像文件格式。
一些图像格式可以处理浮点值(没有剪辑或取整),这样的图像格式包含 NetPBM PFM,这是唯一不需要任何额外的特殊选项的图像文件格式。
也可以使用另外的图像文件格式,但是要求有一个特定的命令来指定文件保存浮点值。
具体的,你需要指定颜色选项”-define quantum:format=floating-point”来要求这些文件格式中的浮点值。
“-depth”设置也可以用来定义使用的浮点值的类型。如果使用的是”-depth 32″或更少(IM的大多数版本的默认值),则”floats”被使用。但是如果设置的是”-depth 64″,则”doubles”将被用于浮点值写入图像文件格式,或者从图像文件格式中读取浮点值。
你可以使用这些特殊标志的图像文件格式包括TIFF, FITS,和 MIFF。原始数据文件格式 RGB 也可以保存和读取浮点值,但需要指定读取的合适设置。
另一种特殊的编码选项是”-define quantum:scale=65535.0″,以便使一个从0.0 到 1.0的标准化的浮点值按比例转换为0.0 到 65535.0的值。因此如果在读取浮点图像时遇到了一个接近纯黑的图像,则使用这个选项来将值按比例转换为合适范围内的值。
直接内存到磁盘的文件格式 MPC,也将保存由IM的HDRI版本使用的浮点值,也不需要任何的标记。
但是和任何MPC 图像文件一样,只有在同一台机器上的完全相同版本的IM将正确地读取这样的文件。因此,它只适用于脚本图像处理中的临时快速阅读文件,而不适用于长期储存。
我应该使用什么Q-级别
我应该使用什么版本的ImageMagick? Q8, Q16, 还是HDRI?Q8有一个更小的内存印迹,因为大多数的图像文件格式的图像值都以8位值存储。对于基本构图、图像格式转换、简单的’once off resize’,或者在图像上画图,Q8版本已经足够好了。
Q16增加了一倍的内存足迹,因为颜色值都是以16位值保存的(更精确)。但是如果你想进行包含许多水平操作的复杂图像处理,如以同一命令,对同一图像进行改变颜色空间、调整大小、扭曲、模糊、阴影等等,则16位更好,因为它会保留图像处理步骤中的低精度的图像。你也可以将它们在命令之间以16位文件格式保存,尽管最后,将以8位图像文件格式存储,就像ICO和JPEG。
Q16 HDRI的是一个新的水平,精确到32位浮点值,它可以使你不用取整和剪切效果来处理变得非常大或者非常小的图像值。你甚至可以处理负值,特别是在一些色彩空间中。本质上,它是用来防止在极端情况下处理图像时丢失数据。如在使用HDRI图像时,傅立叶变换、或者只是更高水平的压缩与扩展,你可能会需要进行对原始数据的数学处理。
Q16是大多数涉及扭曲和多画面构图及图像处理效果的良好中间地带, Q8内存占据很小,但是只能进行简单处理,HDRI只是处理极端情况。
图像密度或分辨率
在内存Quality 和文件格式Depth指定颜色分辨率,图像的密度是图像的空间分辨率。也就是说图像密度(通常以dpi或每英寸点数)定义了每个像素相距多远,从而定义了图像在现实世界中的总尺寸。
如果图像的密度和实际图像的像素是完全不相关的。只是一系列存储在图像中的数据来告知如打印机和显示器等输出设备图像每英寸应该有多少点,或者告知如postscript、PDF、 MWF和SVG等矢量格式像素绘制所使用的真实世界坐标。
你可以在读取或写入图像之前使用”-density”功能,或者在读取图像之后使用”-set density”,来设置图像读取到IM时图像的分辨率或密度。
例如,在600 dpi的200×200像素的图像,在现实世界中,将以1/3平方英寸显示,而一个小的多的72 dpi的72×72像素的图像将以1平方英寸显示,尽管相较而言,其空间质量不会很好。这就是它如何运行的。
“-units”设置可以用来定义密度数据是否以’PixelsPerInch’的默认形式或者以更现代的’PixelsPerCentimeter’的公制单位表达出来了。
记住密度或分辨率仅仅是存储在图像中的数据,对实际图像的像素大小或用来显示图像的数据量没有影响,只有当图像在一个真实世界的设备上显示或者打印的时候才用。
关于图像分辨率和密度的更多信息见Resample Resize Operator的注释。关于文本和字体的分辨率和密度的信息见Pointsize and Actual Font Size。
图像编辑和密度
” photoshop”图像编辑器将图像分辨率的副本保存到一个单独的IM不会触到的文件(命名为’8BIM’)中。因此,如果你使用IM改变图像的分辨率,你需要在将图像加载回”photoshop”之前,将这个文件从图像中剥离出来,否则,你可能看不到任何密度的变化。
你可以使用”+profile 8bim”删除图像中的这个文件。在IM Forum Discussion中,Jesper Nilsson (aka stroker),建议你使用”exiftool’程序来直接修改图像 Photoshop Tags 。
例如:
exiftool -g -Photoshop:XResolution=300 -Photoshop:YResolution=300 file.tif
ImageMagick的特殊控件
IM还有一些用来控制操作、信息汇报和调试的特殊选项。
-version 输出IM的版本、所使用的图像质量和创建的时间。 IM将在输出这些信息之后隐退。 -list 这只是一个信息选项,将在列出所要求的条目之后退出。也就是说你不能和其它选项一 起使用和进行图像处理。这纯粹是为了信息目的,特别是在用来检测输入选项和如果IM 已经使用了特定的选项时。 给定的参数决定了你想列出的信息。例如颜色列表给出了可以使用的颜色(例如被"-fill", "-background", "-mattecolor", "-bordercolor"等使用)。字体列表列出了IM所特有的字体。 这里是一些更为有趣的列表: font 已知的字体(IM还知道X和PS字体) type 文件图片类型("-type")(在IM v6.3.5-7之后) 或者字体列表(在IM之前) color 各种不同颜色选项中已知的颜色名称 dispose 所有的GIF处理设置("-dispose") compose 阿尔法通道可用(包含内部方法) layers 应用了什么多图像"-layers"方法 distort 图像失真的方法 morphology 图像形态方法 command 哪些命令行选项(设置和操作符)可用 list "-list" 可以列出哪些列表 configure 创建ImageMagick的配置参数是哪些 最后的'list'设置'Configure'非常重要,因为它说明了IM创建的时候连接的是哪个程序库 和委托程序库,这在老版本中的标准"-version"输出中被漏掉了。(使用该信息的示例见 Script Version Handling) IM在输出这些信息之后就会退出。 -verbose 报告一些更为复杂操作的更多信息。 例如"-segment"输出大量的颜色数量细节。 "-distort"输出更多信息和'FX'要求的图像失真信息。还在重复"-morphology"操作时监测 变化的数量。 从"info:"和"-identify"中生成更详细的图像信息是尤其有用的。 你可以使用操作的'plus'形式来关闭设置,如"+verbose" -regard -warnings '-regard-warnings'会给出有关图像文件格式的非正式警告。也会导致IM根据错误情况返回 到相应的退出状态。 它可以在脚本中用来'sanitize'不可控来源的图像文件。如果JPEG或TIFF图像不正确、不完 整或者包含位置的配置文件,这个操作会导致IM运行失败和退出。 -precision{number} 控制有效数字的个数。 当IM输出浮点数值作为对各种调试、详细和格式请求的回应时,这个设置设定了你希望输出的 精确度。在默认情况下,通常会限制6个有效数字,这个操作符将增加或减少默认值。也可以 用'MAGICK_PRECISION'环境变量来修改默认的设置6。 它从以下方面影响输出: 更详细的"identify"命令或者"-identify", "-print" 和 "-format"设置 "-fx"操作符中'debug()'的输出和'%[fx:...]'字符串转义序列(见FX, DIY Image processing Operator) 当"-set option:showkernel 1"启用时,"-morphology"选项中的浮点数。 见Displaying the Kernel。 -quiet 不报告警告信息性消息,除了I/O错误或者错选项等错误。当操作产生了没有'real'图像作为 结果时,这对"-crop" 或 "-trim" 和 "-layers optimize"等通常报告'missed images'警 告的尤其有用。 它也可以平息一些可能被IM忽略的未知块的复杂图像文件格式的编码器,比如在IM读取TIFF图 像或者奇怪的MPEG (AVI)视屏格式时。 -respect -parenthesis 导致parenthesis不仅保存和修复的当前图像序列,还保存和修复当前operational settings。 意味着一旦给定,括号内的所有设置都将在括号结束时重置。见上面的Parenthesis and Settings 中的示例。 -ping 在"identify"命令中,IM会避免为获取如图像尺寸等基本信息而完整地读取和解码所有的图像 文件格式。 -monitor 在图像处理,特别是非常大和长的图像处理任务中,报告处理的百分比。 在一个较低级别的API,你可以使用SetImageInfoProgressMonitor() 或 SetImageProgressMonitor() -debug 在各个区域报告IM究竟是如何运行的。 这个参数是由逗号分隔开的操作符列表,如: exception 命令中IM不理解的内容 cache 显示IM缓存所占据的磁盘空间 configure 显示IM搜索尝试找到配置文件 trace 在每个程序开始运行时报告轨迹点 all 显示处理中的所有轨迹,这是非常非常非常冗长的,不推荐使用 annotate 当字体用于"-annotate"时,字体规格的报告。 如果使用了"-debug"日志记录输出的位置是由"log.xml"文件控制的。这是默认设置为"console"。 将它存储到一个文件,<log output="console"/>改为 <log output="file"/>即可。对于 命令行和API使用,你还可以通过IM的行为定义环境变量来设置调试级别。 export MAGICK_DEBUG=all