⚠️ 这是一个非官方翻译网站,与 ImageMagick Studio LLC 无关。准确信息请参阅原文(https://usage.imagemagick.org/resize/index.html)

ImageMagick 示例 -- 调整尺寸或缩放(通用技术)

我们来看看以各种方式放大和缩小图像。图像保持完整无缺,但各个颜色点会被合并或扩展,以占用更小/更大的画布区域。请注意,虽然这与图像的分辨率(每单位真实世界长度的像素数)相关,但分辨率更多是图像最终如何被使用的产物,并不是直接图像处理真正关心的问题。


调整图像尺寸 改变图像大小最明显也最常见的方式就是调整尺寸或缩放图像。图像的内容随之被放大,或更常见地被缩小,以适应所需的尺寸。但虽然实际的图像像素和颜色被修改了,图像所表示的内容本质上保持不变。然而调整图像尺寸可能是个棘手的问题。它可能以非常有害的方式修改图像,而且不存在“最佳方式”,因为何为最佳是主观的,取决于你实际想从调整尺寸过程中得到什么。正因为不存在“最佳”或“完美”的方式,所以有许多你可能想要考虑的选项。IM 一直努力提供各种选项,以在图像尺寸调整中给你最大范围的控制。存在数百种可能性、风格和技术,甚至连调整尺寸的专家都在不断尝试寻找新颖不同的改变图像大小的方法。当然对大多数人来说,常规的默认选项已经足够好了,因为它们就是为通用场景而设计的。调整尺寸操作符经过非常精心的设计,力求为真实世界的图像产生非常好的结果。也就是说,并不是说你不能把它用于图表或线条画,不过对于那类图像,你可能需要使用我们稍后会看到的一些更高级的选项。
在指定要调整尺寸的图像时,你首先应该考虑的是……
你真的想修改这张图像吗? 调整尺寸会对图像造成剧烈的改变,避免或尽量减少不想要的“伪影(artifacts)”是最重要的。也许只是对边缘稍作 Shave(修边),或者对图像做更一般性的 Crop(裁剪),会比整体调整图像尺寸产生更好、更理想的结果。它通常看起来更好,而且保留下来的区域是原图的完美副本。因为通常不调整图像尺寸反而更好……

如果调整后的图像与原来尺寸相同,调整尺寸将什么也不做。

这一点的例外(总会有例外)是:如果你实际上用“[-filter](https://imagemagick.org/command-line-options/#filter)”设置指定了一个重采样滤镜(Resampling Filter)。在这种情况下,正常的“若图像未被调整尺寸则什么也不做”会被覆盖,滤镜将被应用。然而许多滤镜(即便是默认滤镜)也会让图像略微模糊。这是它们本性的一部分。所以通常这种针对空操作调整尺寸的“短路”是件好事。调整尺寸操作符的参数是图像应被装入的区域。这个区域不是图像的最终尺寸,而是图像要装入的区域的最大尺寸。也就是说,因为 IM 更倾向于保持图像的宽高比而非最终尺寸(除非给出 '!' 标志),但最终尺寸中至少有一个(即便不是两个)应当与给定的图像参数匹配。所以让我说清楚……

调整尺寸会把图像装入(fit into)所请求的尺寸内。
不会填满(fill)所请求的方框尺寸。

保持宽高比基本上是为了让输入图像中的任何圆形在输出图像中仍然是圆形。也就是说,图像不会被压扁或挤压,只会被调整尺寸,除非你另行指定。例如,这里我尝试把两张源图像(一张较大、一张较小)装入一个 64x64 像素大小的方框中。

  magick dragon_sm.gif    -resize 64x64  resize_dragon.gif
  magick terminal_sm.gif  -resize 64x64  resize_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

如你所见,“[-resize](https://imagemagick.org/command-line-options/#resize)没有生成一张 64x64 的方形图像。实际上图像只是被放大或缩小到恰好最适合装入给定尺寸的程度。 忽略宽高比('!' 标志)
如果你愿意,可以强制“[-resize](https://imagemagick.org/command-line-options/#resize)”忽略宽高比并扭曲图像,使其总是生成恰好为指定尺寸的图像。这通过在尺寸后面添加字符 '!' 来完成。遗憾的是,这个字符有时也会被各种 UNIX 命令行 shell 用作特殊用途。所以你可能需要以某种方式转义该字符以保留它。

  magick dragon_sm.gif    -resize 64x64\!  exact_dragon.gif
  magick terminal.gif  -resize 64x64\!  exact_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

仅缩小较大的图像('>' 标志)
另一个常用的选项是限制 IM,使其只把图像缩小以装入给定尺寸,而绝不放大。这就是 '>' 调整尺寸选项。可以把它理解为只对“大于(greater than)”给定尺寸的图像应用调整尺寸(这有点反直觉)。

  magick dragon_sm.gif    -resize 64x64\>  shrink_dragon.gif
  magick terminal.gif  -resize 64x64\>  shrink_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

这个选项对于节省图像的磁盘空间,或在生成缩略图时通常非常重要,因为普遍放大图像往往并不可取,它会产生“模糊”的放大效果。 仅缩小标志('>' 标志)在 UNIX Shell 和 Windows 批处理脚本中都是特殊字符,你需要转义该字符(在 shell 中用反斜杠 '\>',在 windows 批处理中用 '^>')。它在 HTML 网页中也是特殊字符,所以 PHP 脚本也可能需要一些特殊处理。
仅放大较小的图像('<' 标志)
与上一个标志相反的是 '<',它只放大小于给定尺寸的图像,很少被使用。最值得一提的用法是配合诸如 '1x1<' 这样的参数。这个调整尺寸参数永远不会真正调整任何图像的尺寸。换句话说它是个空操作(no-op),它能让你在那些总是使用“[-resize](https://imagemagick.org/command-line-options/#resize)”的程序和脚本中短路掉一次调整尺寸操作。除此之外你大概并不会真的想用这个特性。使用这个“短路”参数的一个例子是用于“magick montage”的“[-geometry](https://imagemagick.org/command-line-options/#geometry)”设置。详见 Montage 与 Geometry,需要谨慎 仅放大标志('<' 标志)在 UNIX Shell 和 Windows 批处理脚本中都是特殊字符,你需要转义该字符(在 shell 中用反斜杠 '\<',在 windows 批处理中用 '^<')。它在 HTML 网页中也是特殊字符,所以 PHP 脚本也可能需要一些特殊处理。
--- ---
填充区域标志('^' 标志)
从 IM v6.3.8-3 起,IM 现在有了一个新的 geometry 选项标志 '^',用于基于最小的装入维度来调整图像尺寸。也就是说,图像被调整尺寸以完全填满(甚至溢出)给定的像素区域。
  magick dragon_sm.gif    -resize 64x64^  fill_dragon.gif
  magick terminal.gif  -resize 64x64^  fill_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

就其本身而言,这个选项似乎不太有用,但当它与居中(或不居中)的“[-crop](https://imagemagick.org/command-line-options/#crop)”或“[-extent](https://imagemagick.org/command-line-options/#extent)”结合以移除图像多余的部分时,你就可以让图像完全填满所指定的区域。调整尺寸的参数和最终图像尺寸的参数应当是相同的值。虽然“[-crop](https://imagemagick.org/command-line-options/#crop)”最合乎逻辑,但它可能需要额外的“[+repage](https://imagemagick.org/command-line-options/#repage)”来移除虚拟画布的图层信息。“[-extent](https://imagemagick.org/command-line-options/#extent)”不需要这种清理,但仍然允许使用“[-gravity](https://imagemagick.org/command-line-options/#gravity)”来定位。更多信息见 裁切与加边框

  magick dragon_sm.gif      -resize 64x64^ \
          -gravity center -extent 64x64  fill_crop_dragon.gif
  magick terminal.gif    -resize 64x64^ \
          -gravity center -extent 64x64  fill_crop_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

此外,“[-extent](https://imagemagick.org/command-line-options/#extent)”可用于对使用普通调整尺寸的图像进行填充补足(配合“[-background](https://imagemagick.org/command-line-options/#background)”颜色设置)。关于这类操作的更多内容,见 缩略图:装入给定空间小结 记住这需要 IM v6.3.8-3 或更高版本才能使用。否则请使用下面较旧的调整尺寸以填充给定空间技术。
填充区域标志('^' 标志)在 Windows 批处理脚本中是特殊字符,你需要通过将其加倍来转义该字符。例如 '^^',否则它将不起作用。关于此点及其他 windows 特殊之处,见 Windows 批处理脚本
--- ---
百分比调整尺寸('%' 标志)
在“[-resize](https://imagemagick.org/command-line-options/#resize)”参数中添加百分号 '%',会使调整尺寸按指定的量来缩放图像。
  magick dragon_sm.gif    -resize 50%  half_dragon.gif
  magick terminal.gif  -resize 50%  half_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

但要注意,图像最终的像素尺寸会被四舍五入到最近的整数。也就是说,你不会在图像边缘生成部分像素!因此实际的缩放可能与你提供的缩放因子不完全匹配,X 和 Y 方向甚至可能略有不同,但会非常接近。(见下面的使用 Distort 调整尺寸)。 如果你真的想让图像调整尺寸后看起来像是有部分像素的尺寸差异,可以使用通用扭曲操作符(General Distortion Operator),特别是 Scale-Rotation-Translate(见下面的 Distort 调整尺寸)。
百分比调整尺寸标志('%' 标志)在 Windows 批处理脚本中是特殊字符,你需要通过将其加倍来转义该字符。例如 '%%',否则它将不起作用。关于此点及其他 windows 特殊之处,见 Windows 批处理脚本
--- ---
_所有这些“标志”选项 '!'、'<'、'>'、'^'、'%' 和 '@' 都只是“[-resize](https://imagemagick.org/command-line-options/#resize)”操作符的开/关开关。重要的只是该字符在调整尺寸参数中是否出现(或缺失),而不是它们的位置。它们可以出现在参数的开头或结尾,或在各个数字之前或之后(不过不能出现在数字中间)。

也就是说,'%50' 与 '50%' 的效果完全相同,不过后者为了可读性更受推荐。此外 '50%x30' 实际上意味着 '50%x30%',而不是像你可能以为的那样表示宽度 50% 和高度 30 像素。

对于所有使用“geometry”样式('WxH' 或 '+X+Y')参数的 IM 参数,情况都是如此。然而诸如 '+X+Y' 这样的偏移量永远不会被当作百分比处理。_
---|---
使用像素面积计数上限调整尺寸('@' 标志)
还有最后一个“[-resize](https://imagemagick.org/command-line-options/#resize)”选项标志。“at”符号 '@' 会把图像调整尺寸到包含不超过给定数量的像素。例如,这可以用来把一组各种不同尺寸的图像调整到大致相同的大小。例如,这里我们把两张图像都调整到大约 64x64 的尺寸,即 4096 像素大小。

  magick dragon_sm.gif    -resize 4096@  pixel_dragon.gif
  magick terminal.gif  -resize 4096@  pixel_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

请注意,最终图像尺寸不限于高度或宽度 64 像素,而是会拥有一个尽 IM 所能接近(但小于)该大小的面积。这意味着一个维度通常会略大于 64 像素,另一个会略小。在某些方面这是缩略图化图像的理想折中。见 按面积装入的缩略图尺寸。你也可以加上 '>' 标志,以只缩小那些像素数超过计算值的图像,而保持那些已经小于该尺寸的图像不变。 | _遗憾的是,使用“面积调整尺寸(Area Resize)”时,' <'(放大较小图像)标志目前会被忽略。

_
---|---
在图像读取时调整尺寸
调整尺寸操作符也可以在图像被读入之后立即应用,在它被加入当前图像序列、读取下一张图像之前。这样读入大量图像只需最少量的内存。更多细节见 图像读取修饰符。例如……

  magick dragon_sm.gif'[64x64]'    read_dragon.gif
  magick terminal.gif'[64x64]'  read_terminal.gif

[IM Output] [IM Output] [IM Output] [IM Output]

这种技术唯一的问题是,在图像读取过程中无法使用任何特殊的调整尺寸选项。 在 v6.2.4 之前,调整尺寸与透明度对 ImageMagick 构成了一个问题,会在透明背景上的浅色物体周围产生黑色光晕效果。从那个版本起,这个问题经过研究最终得到修复。关于这个旧 bug 的更多细节,见调整尺寸光晕 Bug

其他调整尺寸操作符 Geometry —— 只调整最后一张图像Geometry 是一个非常特殊的选项。该操作符在每个 IM 命令中的行为都略有不同,而且常常以特殊而神奇的方式表现。其原因大多是出于历史遗留用法,如有可能应尽量避免使用。首先,在“magick display”中,它用于设置正在显示的图像窗口的尺寸和位置。这是 IM 最初启动时它原本的用法和含义。正是从这一点衍生出了它其他的“调整尺寸”能力。对于“montage”,“[-geometry](https://imagemagick.org/command-line-options/#geometry)”是一个设置,会被保存直到所有参数都被读入。此时它定义最终的瓦片(单元格)尺寸(或者把它交由“magick montage”来计算),而位置参数则用于指定瓦片单元格周围的间距。见 Montage 控制设置。在“[composite](basics.html#composite)”中,“[-geometry](https://imagemagick.org/command-line-options/#geometry)”同样会被保存直到参数读取结束。然后它用于在叠加图像(给定的第一张图像)被叠加到背景图像(第二张图像)之上之前,对其调整尺寸和定位。例如见 合成多张图像。如你所见,它在大多数 IM 命令中用作一个“设置”,但在“magick”中,“[-geometry](https://imagemagick.org/command-line-options/#geometry)”既是一个特殊的图像调整尺寸操作符,又是一个定位设置。它的作用是仅对当前图像序列中的最后一张图像执行“[-resize](https://imagemagick.org/command-line-options/#resize)”。这是唯一一个专门设计为只影响当前图像序列中那一张图像(最后一张)的图像处理操作符。让这个特殊选项更复杂的是,“[-geometry](https://imagemagick.org/command-line-options/#geometry)”选项中的位置部分会被“magick”命令保存下来,就像在“[composite](basics.html#composite)”中那样。也就是说,任何位置都会被保留,供之后的“[-composite](https://imagemagick.org/command-line-options/#composite)”使用,以将“叠加”图像(当前图像序列中倒数第二张图像)定位在“背景”图像(图像序列中的第一张图像)之上。因此,你应当把“magick”命令中“[-geometry](https://imagemagick.org/command-line-options/#geometry)”的使用限制在某次“[-composite](https://imagemagick.org/command-line-options/#composite)”或“[-layers](https://imagemagick.org/command-line-options/#layers) composite”操作之前不久。总而言之,这个操作符真正有用的场合,只有在读取或创建第二张图像之后、你即将对这些图像执行某种Alpha 合成处理之前。关于使用“[-geometry](https://imagemagick.org/command-line-options/#geometry)”来调整尺寸/定位图像的实际示例,见 合成多张图像。 Thumbnail —— 调整尺寸并剥离配置文件“-thumbnail”操作符是“[-resize](https://imagemagick.org/command-line-options/#resize)”的一个变体,专为把非常非常大的图像缩小成小缩略图而设计。首先它使用“[-strip](https://imagemagick.org/command-line-options/#strip)”移除图像中所有的配置文件和其他冗余信息。然后它使用“[-sample](https://imagemagick.org/command-line-options/#sample)”把图像缩小到最终高度的 5 倍。最后它做一次普通的“[-resize](https://imagemagick.org/command-line-options/#resize)”把图像缩减到最终尺寸。所有这些基本上是为了加快从非常大的文件生成缩略图的速度。不过对于 JPEG 图像的缩略图,你可以使用特殊选项“-define jpeg:size=”设置来限制从磁盘读入的图像尺寸。更多细节见 读取 JPEG 图像。因此,在 JPEG 缩略图生成中这种速度改进很少需要,不过剥离配置文件仍然非常重要。对于其他图像格式,如 TIFF,剥离配置文件和速度改进都仍然至关重要。因此它仍然是为创建缩略图而调整图像尺寸的推荐方式。 在 IM v6.5.4-7 之前,“[-thumbnail](https://imagemagick.org/command-line-options/#thumbnail)”会剥离图像中所有的配置文件,包括 ICC 颜色配置文件。从这个版本起,颜色配置文件将被保留。如果不想要颜色配置文件,则用“[-strip](https://imagemagick.org/command-line-options/#strip)”剥离所有配置文件。
Resample —— 改变图像的分辨率正如前面那些替代性的调整尺寸操作符一样,“-resample”也只是对普通“[-resize](https://imagemagick.org/command-line-options/#resize)”操作符的一个简单封装。然而它的目的是调整图像中的像素数量,使图像在以给定分辨率或密度显示时,按真实世界的尺度看起来仍然是相同的大小。也就是说,给定图像在像素数量上被放大或缩小,而图像以真实世界单位计的尺寸保持不变。它意在用于那些从特定分辨率或密度的程序或设备读入、或将要写出到此类程序或设备的图像。这对于调整图像以适配特定的硬件输出设备尤为重要,无论是显示器、打印机,还是特定分辨率的 postscript 或 PDF 图像格式。只需记住图像的真实世界尺寸不会改变,只有它的分辨率以及当然还有用于表示图像的像素数量会改变。例如,假设你有一张以 300dpi(每英寸点数)扫描的图像。该图像以这个分辨率(密度)被保存,或者当你把它读入 IM 时,你将其指定为 300dpi 图像(使用“[-density](https://imagemagick.org/command-line-options/#density)”)。现在你决定在一个分辨率为 90dpi 的屏幕上显示它,于是你做一次“-resample 90”。IM 现在会把图像调整尺寸 90/300,即缩小到原图尺寸的 30%,并将图像的新密度设为 90dpi。图像现在在所用像素数量上变小了,但若在 90dpi 显示器上显示,它将以与你扫描的原图相同的物理尺寸呈现。也就是说,它现在拥有适合 90dpi 显示器的分辨率,因此会以其原本的真实世界尺寸显示给用户。在某些情况下,可能需要一个“[-units](https://imagemagick.org/command-line-options/#units)”设置(参数为 'PixelsPerInch' 或 'PixelsPerCentimeter')才能让这个操作符正确工作。这个设置对于输出到 Postscript 和 PDF 图像文件格式也可能很重要。请注意,只有少数图像文件格式(如 JPEG、PNG 和 TIFF)能够将图像分辨率或密度与图像数据一起存储。对于不支持图像分辨率的格式,或多分辨率(基于矢量)的图像格式,图像的原始分辨率必须在读入之前通过“[-density](https://imagemagick.org/command-line-options/#density)”属性指定(见 密度图像元数据)。如果没有设置密度属性,IM 将假定它具有默认密度 72dpi。在读入此类图像之后设置密度,只会影响其输出分辨率,而不会影响其以像素计的最终尺寸。 Scale —— 用像素平均进行缩小“-scale”调整尺寸操作符是调整尺寸命令的一个简化、更快的形式。放大图像时,图像中的像素会被复制以形成大块的矩形色块。这对于展现图像清晰、不模糊的放大效果很好。例如,这里是某个内置瓦片图案的放大视图……
  magick -size 8x8 pattern:CrossHatch30 -scale 800% scale_crosshatch.gif

[IM Output]
通常会使用 100% 的倍数这样的单一百分比值来进行图像放大,以确保所有像素都被放大相同的量,否则你可能会得到不同大小的像素行和列,从而产生大尺度的摩尔纹(Moiré pattern)。 例如,这里我用一个不是原图尺寸倍数的大小,糟糕地缩放了一个看起来平滑的“50% 灰格”图案。 |

  magick pattern:gray50 scale_gray_norm.gif
  magick pattern:gray50 -scale 36 scale_gray_mag.gif

[IM Output]

[IM Output]
缩小图像时,相邻的像素会被平均在一起以产生一个新的彩色像素。例如,把图像缩放到原尺寸的 50%,实际上会把每 4 个像素一组平均在一起以创建一个新像素(前提是图像尺寸也是 2 的倍数)。不过仍需谨慎,因为缩放缩小后的图像也可能产生摩尔纹,除非新图像是精确的整数倍缩减(一种称为“合并(binning)”的技术),这也要求原图尺寸是最终尺寸的某个精确整数倍。此外,用“[-scale](https://imagemagick.org/command-line-options/#scale)”大幅缩小的真实世界照片往往看起来过于锐利,沿锐利边缘出现锯齿(“阶梯状”)效果。“[-scale](https://imagemagick.org/command-line-options/#scale)”的像素平均使它能够生成“像素化”的图像。你基本上是把图像尺寸缩小以平均像素,然后再放大回图像的原始尺寸。

  magick rose: -scale 25%  -scale 70x46\!  rose_pixelated.gif

[IM Output] [IM Output]

你可以用一个遮罩把上面这张像素化图像与原图组合起来,从而“隐藏”原图中某个小得多的“不雅”部位。这种技术的演示见 保护某人的匿名性 示例。该算法的设计还是先遍历像素行再遍历列,这与“[-resize](https://imagemagick.org/command-line-options/#resize)”相反。这可能让“[-scale](https://imagemagick.org/command-line-options/#scale)”能更好地处理“mpc:”磁盘缓存图像。 直到 IM v6.4.7 为止,“[-scale](https://imagemagick.org/command-line-options/#scale)”仍然包含旧的调整尺寸光晕 Bug
Scale 内部原理(像素混合)……在许多方面,Scale 操作符类似于普通的Resize 操作符,只是使用了一个“[Box](filter.html#box)重采样滤镜。然而它实际上使用了一个完全不同的算法,其结果比 Box 滤镜 所产生的略微更准确。Box 滤镜的工作方式是简单地平均落在滤镜“支持窗口”内的任何像素(采样)(见 滤镜支持专家控制)。这意味着当把图像缩小很小的量时,Box 滤镜的调整尺寸只会产生要么是精确的像素值、要么是完美平均的像素值。然而 Scale 操作符 使用一种不同的算法,称为(在没有更好的名称时)像素混合(Pixel Mixing)。它不是基于支持窗口内的“像素平均”来生成颜色,而是使用支持窗口内更准确的“像素面积”。例如,这里我取一个“棋盘格”像素图案,把它缩小 2 个像素,将 Scale 的结果与使用非常简单的 Box 和 Triangle 滤镜 调整尺寸的结果进行比较。
  magick -size 10x10 pattern:gray50  checks.gif
  magick checks.gif  -filter box      -resize 8x8  checks_box.gif
  magick checks.gif                   -scale  8x8  checks_scale.gif
  magick checks.gif  -filter triangle -resize 8x8  checks_triangle.gif

[IM Output]
10 像素“井字格” | | [IM Output]
Box 滤镜
调整尺寸 | [IM Output]
像素混合
Scale | [IM Output]
Triangle 滤镜
调整尺寸
---|---|---|---|---
上面的图像已被大幅放大

上图展示了“纯平均”、“像素混合”和“线性插值”各自得到的结果。它也展示了 Scale 操作符 实际上与 Triangle 滤镜 相似,但只在对图像做非常小的缩小时如此。在其他情况下(强烈缩小、放大或精确整数尺寸调整),它会产生更像 Box 滤镜 的结果。基本上,它生成的东西更像是 Box 和 Triangle 滤镜之间的某种混合,具体取决于图像被缩减的确切程度。放大时你会看到类似的效果。

  magick -size 8x8 pattern:gray50  checks_sm.gif
  magick checks_sm.gif -filter box      -resize 10x10 checks_sm_box.gif
  magick checks_sm.gif                  -scale  10x10 checks_sm_scale.gif
  magick checks_sm.gif -filter triangle -resize 10x10 checks_sm_triangle.gif

[IM Output]
10 像素“井字格” | | [IM Output]
Box 滤镜
调整尺寸 | [IM Output]
像素混合
Scale | [IM Output]
Triangle 滤镜
调整尺寸
---|---|---|---|---
上面的图像已被大幅放大

放大时,Box 滤镜永远不会产生“平均像素”,只会产生像素行/列的复制。然而 Scale 会沿边缘生成平均的颜色像素,同样很像但并不完全等同于 Triangle 滤镜。当然这种效果只有在小幅、非整数放大时才真正可见,而在较大的缩放中,只在边缘处出现,在更典型的情形下你可能会得到一两个平均像素。总结:Scale 比普通的 Resize 操作符 快得多,因为它在图像处理需求上不那么通用。但它也是一个完全不同的算法,在用非整数比例调整图像尺寸时会产生略微不同的结果。更多细节见 像素混合(Pixel Mixing) 页面,以及 IM 论坛讨论 线性放大几个像素。特别感谢论坛用户 atnbueno,他指出了上述差异。 Sample —— 通过行/列复制/删除调整尺寸“-sample”调整尺寸操作符是最快的调整尺寸操作符,尤其在大规模图像缩减中。事实上它甚至比“[-scale](https://imagemagick.org/command-line-options/#scale)”操作符(见上文)还要快。放大图像时,它只执行像素复制(如同 Box 滤镜),生成矩形的像素“色块”。然而缩小图像时,“[-sample](https://imagemagick.org/command-line-options/#sample)”只是删除像素的行和列。因为整行整列的像素被简单地添加或移除,“[-sample](https://imagemagick.org/command-line-options/#sample)”不会生成任何新的或额外的颜色。这一事实对于某些图像处理技术(例如调整 GIF 动画的尺寸)可能很重要。另一种看待方式是,图像中以一种非常均匀规则的模式在整张图像上“采样”了单个独立的像素。你可以把图像想象成被划分为一个区域数组,从每个区域中选取一个像素用于结果图像。然而这种对单个像素的“采样”(或整行整列的移除)可能会产生相当糟糕的结果,尤其是对于含有细线(以像素宽度计)的图像。例如,这里我画一条线,但随后缩减图像尺寸,结果只剩下一行点。

  magick -size 150x60 xc: -draw 'line 0,59 149,0' line_orig.gif
  magick line_orig.gif  -sample 50x20  line_sample.gif

[IM Output] [IM Output]

这是图像采样常见的典型效果,称为严重的混叠(Aliasing)效果。 被采样像素的偏移从 IM v6.8.4-7 起,每个采样子区域中被采样的确切像素,现在定义为每个区域中点处的像素(如果子区域是偶数个像素,则为左上角的中心像素)。这意味着如果你对一张图像做单像素采样,你将得到图像的中间像素。 在 IM v6.8.4-7 之前,被选中的像素是每个区域的左上角像素。然而有报告称某些版本中这可能是右下角,或者由于 bug,它甚至可能略有变化。
这类信息对于按原图尺寸的整数除法进行缩减的图像尤其有用。例如当你创建或采样像素化图像,或 对视频帧去隔行 时。此外从该版本起,你可以使用 definesample:offset”精确控制每个子区域中选取哪个像素,它接受一个或两个百分比值(默认为 '50',即中点)。注意这里用百分比,因为在一般情况下“采样子区域”可能不与像素边界对齐。这就是为什么需要的是百分比而非“像素偏移”。然而如果图像尺寸能被采样数整除,那么你就可以轻松计算出你想从每个子区域中取的确切像素。例如,如果一张图像采样后得到 5 像素的子区域(例如,把一张横向 100 像素的图像采样缩小到 20 个像素样本),那么你可以使用 0 到 19.9 范围内的采样偏移百分比来选取每个区域的第一个像素,20.1 到 39.9 选取第二个,以此类推。换句话说,你可以使用 10、30、50、70 和 90 这些百分比值来精确指定你想从每个固定大小的采样区域中取哪个像素。关于采样偏移的更多内容,见 IM 论坛讨论 采样点。 Magnify —— 像素缩放“-magnify”选项把图像尺寸加倍,但它是通过一种称为“像素缩放(Pixel Scaling)”、使用 Scale2X 算法 的技术来实现的。这种算法试图在放大像素时平滑像素的角落,而不添加额外的颜色。这样非常小的像素化图像能更干净地放大,同时保留原图的颜色和较小图像的“复古像素风”。
  magick -size 8x8 pattern:CrossHatch30 -virtual-pixel tile \
          -magnify -magnify -magnify magnify_crosshatch.gif

[IM Output] [IM Output]

注意这里使用了 虚拟像素(Virtual Pixel) 设置,以确保 magnify 理解这张特定图像在图像边缘处是“环绕”的。 在 IM v6.8.4-10 之前,magnify 只是对调整尺寸的一个封装,用于把图像尺寸加倍。不太有用,也很少被使用。使用“像素缩放”使这个选项有用得多。更多信息见 IM 用户论坛上的 像素缩放
在很多 API 中也常提供一个“Minify()”函数,用于把图像尺寸减半,但它只是对调整尺寸的一个封装。然而“-minify”在命令行 API 中不可用,至少在撰写本文时是这样。
--- ---
Adaptive Resize —— 不模糊的小幅调整尺寸“-adaptive-resize”操作符使用特殊的 网格插值(Mesh Interpolation) 方法来调整图像尺寸。例如,这里我对一条简单的线调整尺寸,先用普通的“[-resize](https://imagemagick.org/command-line-options/#resize)”,再用“[-adaptive-resize](https://imagemagick.org/command-line-options/#adaptive-resize)”。
  magick -size 50x50 xc: -draw 'line 0,49 49,0'  line_orig2.gif
  magick line_orig2.gif           -resize 80x80  line_resize.gif
  magick line_orig2.gif  -adaptive-resize 80x80  line_adaptive.gif

[IM Output] [IM Output] [IM Output]

如果你查看这两个结果的放大图……

[IM Output] [IM Output]

你可以看到右侧的 Adaptive 调整尺寸 图像比左侧用普通“[-resize](https://imagemagick.org/command-line-options/#resize)”操作符产生的图像看起来干净得多、也不那么模糊。基本上该操作符避免了“[-resize](https://imagemagick.org/command-line-options/#resize)”操作符在颜色急剧变化时可能产生的过度模糊。这对于轻微的图像尺寸调整效果很好,尤其是对放大,特别是对于具有急剧颜色变化的图像。然而与所有像素插值方法一样,当图像被放大或缩小超过 50% 时,它会产生混叠和摩尔纹效果。你也可以用一次 Distort 调整尺寸 操作并配合选项“-filter point -interpolate mesh”来生成完全等价的结果。也就是说,使用简单的 网格插值 查找方法、而非更复杂的重采样滤镜来调整图像尺寸。 Interpolative Resize —— 使用插值方法调整尺寸“-interpolative-resize”操作符与前面的 Adaptive Resize 操作符实际上几乎完全相同。然而这个操作符将使用当前的“[-interpolate](https://imagemagick.org/command-line-options/#interpolate)”设置,而非固定的“Mesh”插值方法。

如果你使用“[Nearest](misc.html#nearest)”的“[-interpolate](https://imagemagick.org/command-line-options/#interpolate)”设置,你基本上会得到等价于 Sample 操作符 的结果。类似地,许多其他 简单插值方法 将等价于使用相应的 插值调整尺寸滤镜。但有一些插值方法,如 Mesh,作为调整尺寸滤镜没有等价物。

这同样是一种非缩放的调整尺寸,这意味着它对放大和小幅缩小效果很好,但当缩小超过 50% 时,会出现严重的 混叠效果,正如上面其他“采样型调整尺寸操作符”所示。 Liquid Rescale —— 接缝裁剪(Seam Carving)正如对图像进行 采样 通过直接移除或复制整列整行来调整尺寸一样,特殊的 IM 操作符“[-liquid-rescale](https://imagemagick.org/command-line-options/#liquid-rescale)”也通过移除或复制图像的像素列和行来缩小/放大图像。区别在于它试图以更智能的方式来做到这一点。首先,它不是移除简单的一线像素,而是移除一条“接缝(seam)”像素。也就是说,那条可以以最多 45 度的角度在图像中蜿蜒曲折的列(或行)。其次,它试图移除那些在图像内容方面“重要性最低”的接缝。它如何选择是依据图像的能量,或者更简单地说,依据某条特定“接缝”所涉及的颜色变化量。变化量最少的“接缝”会被首先移除,接着是能量更高的“接缝”,直到图像达到所需的尺寸。关于液态调整尺寸和接缝裁剪的更详细信息,见 Wikipedia:接缝裁剪YouTube 视频演示,以及 PDF 论文:用于内容感知图像调整尺寸的接缝裁剪。例如,这里是 IM 徽标使用 IM “[-liquid-rescale](https://imagemagick.org/command-line-options/#liquid-rescale)”操作符被调整得更小的样子。

  magick logo: -resize 50% -trim +repage  logo_trimmed.jpg
  magick logo_trimmed.jpg  -liquid-rescale 75x100%\!  logo_lqr.jpg
  magick logo_trimmed.jpg  -sample 75x100%\!  logo_sample.jpg

[IM Output]
原图 | | [IM Output]
液态调整尺寸 | [IM Output]
采样
---|---|---|---

注意“[-liquid-rescale](https://imagemagick.org/command-line-options/#liquid-rescale)”如何保留了复杂的巫师,同时挤压了图像中不那么复杂的星星和标题部分。它也稍微挤压了巫师的右脚,在斗篷边缘产生了一点锯齿,就像它对巫师那细但简单的魔杖所做的那样。另一方面,Sample 调整尺寸 图像只是移除了等间距的像素列,导致整张图像变得同样扭曲。星星没有被完整保留,所有边缘都有明显但均匀的 混叠 效果。基本上,“[-liquid-rescale](https://imagemagick.org/command-line-options/#liquid-rescale)”会产生一张总体上看起来更好的“被挤压”图像,而不会生成额外的“混合颜色”或模糊图像。不过你可能会在某一处(本例中是巫师的魔杖)得到轻微但局部的混叠效果,而不是把那种效果扩散到整张图像。它也能放大图像,方法是把图像中找到的接缝“加倍”。

  magick logo_trimmed.jpg  -liquid-rescale 130x100%\!  logo_lqr_expand.jpg

[IM Output] [IM Output]

如你所见,它首先尝试(在可能的地方)把各个物体之间的间距加倍,把它们拉开。不过在本例中,最左边的星星和那个“m”变得扭曲了,因为穿过这些“低能量”区域的“接缝”被聚集到了一起。但请注意,它只会把每条接缝加倍一次,因此当图像被放大太多时,这种技术就开始失效。一个更好的方法通常是先把图像调整得更大,然后用液态调整尺寸把它缩减到所需尺寸。或者分多个较小的步骤使用“[-liquid-rescale](https://imagemagick.org/command-line-options/#liquid-rescale)”。为了更好地展示“[-liquid-rescale](https://imagemagick.org/command-line-options/#liquid-rescale)”的效果,这里是一个动画,同一张图像先被缩小到非常细,然后再放大。这个动画是用 shell 脚本 animate_lqr 创建的。

[IM Output]

再次注意,随着图像被压缩进越来越小的区域,它如何试图保留图像中最复杂的部分。也就是说,标题中的空白被优先压缩,然后是巫师的手臂,然后是巫师的右侧,把巫师最复杂的中间部分留到最后。特别看星星在最终被液态调整尺寸所实现的重采样像素移除影响之前,如何被挤压到一起。(接下来见问题)你可以把液态调整尺寸想象成试图像挤海绵那样压缩图像,开阔区域被首先压缩,把笨重且结构更复杂的部分留到最后。接缝裁剪的问题 液态调整尺寸,或称接缝裁剪,纯粹通过从图像中移除整个像素来工作。因此,像 采样 一样,它不会生成或合并颜色,图像内的直线和图案可能因该操作而严重扭曲。基本上它可能导致严重的 混叠效果,除非同时应用某种平滑方法。不过通常混叠效果会被分组并局限于图像中不那么复杂的区域,而不是扩散到整张图像。这正是它效果如此之好的唯一原因!由于“接缝”可以在图像中蜿蜒曲折,接缝可以、而且常常看起来会绕过复杂的物体,在尝试压缩物体本身之前先移除物体之间的空间。例如,注意上面演示中的单词“Image”如何看起来被塞到标题中其他字母下面而没有太多扭曲。然而这种左右移动被限制在 45 度角内。对于背景“繁忙”而前景物体不那么“繁忙”的图像,例如含有人脸的照片,能量函数可能会假定前景物体不如背景重要。这会导致一些严重的不良副作用,可能需要人工干预来解决。 | _液态调整尺寸目前是一个高度实验性的操作,添加于 IM v6.3.8-4。它需要先安装“liblqr”委托库才能为你工作。

目前尚未提供专家级用户控制。诸如修改所用内容能量函数、使用用户提供的保留/移除滤镜(调整该能量函数)、访问中间接缝裁剪图像,以及该库还提供的其他功能等控制。可以假定这类控制将在未来某个时候随着用户的需求、以及我们获得对库函数更多的内部控制而提供。

警告 不要期望它会保持现在实现的样子。它是高度实验性的,预计会在功能上发生变化和扩展。_
---|---
Distort Resize —— 自由形式调整尺寸上面所有的调整尺寸方法都有一个我们早先提到过的局限:它们会把新图像的尺寸四舍五入到整数个像素,然后把旧图像的像素映射到新的像素阵列。这有两个影响。第一,当调整到非常小的尺寸时,结果图像的 X 缩放可能与 Y 缩放不完全匹配(宽高比略有不同)。这种差异很小,除非你做到非常小,否则通常不易察觉。另一个影响是你无法把图像调整尺寸到一个含有部分像素边缘的区域,而这在进一步处理(如图像叠加)中可能很重要。它还意味着你无法用调整尺寸把图像仅仅向右平移半个像素(而不实际调整尺寸),尽管该算法完全可以轻松做到这一点。从 IM v6.3.6 起,通用扭曲操作符[-distort](https://imagemagick.org/command-line-options/#distort)”将让你做到这一点以及更多,使用它的 Scale-Rotate-Translate 扭曲方法。你也可以基于控制点的移动,使用 Affine 扭曲来做到这一点。然而请注意,因为图像的边缘可以包含部分像素,最终图像可能会比你预期的大 2 到 3 个像素。多出来的周围像素将根据当前的 虚拟像素 设置进行混合,你通常会把它设为透明。例如,这里我把玫瑰图像调整到原尺寸的 90%(.9),不旋转(0),围绕图像中心缩小它(若未指定,则为默认控制点)…… |

  magick rose: -alpha set -virtual-pixel transparent \
          +distort SRT '.9,0' +repage  rose_distort_scale.png

[IM Output]
它看起来可能不像是改进,事实上它有模糊的边缘,但它是一次精确的调整尺寸,没有为迁就整数的最终图像尺寸而做调整,正如你所请求的那样。正因如此,边缘是模糊的,因为像素颜色被铺展在像素尺寸的若干分之一上,而不仅仅是铺到整数上。注意我使用了“[+distort](https://imagemagick.org/command-line-options/#distort)”的“加号”形式,以便让这张图像的处理操作符正确地设置 虚拟画布 上最终图像的尺寸和偏移,供进一步处理和分层之用。如果不想要这个偏移,可以用“[+repage](https://imagemagick.org/command-line-options/#page)”操作符移除它。但如果保留它,那么图像在更大画布上的实际位置将被保留,让你能够把图像连同其“模糊边缘”精确地正确定位。这里我调整了它的尺寸,使左上角(0,0)向右移动 .5 像素(到 .5,0),图像其余部分围绕该控制点缩放…… |

  magick rose: -alpha set -virtual-pixel transparent \
          +distort SRT '0,0  .9  0  .5,0' +repage  rose_distort_shift.png

[IM Output]
注意由于顶部边缘实际上没有移动,它保持相对锐利,而所有其他边缘都变得模糊。这里是顶角的一个像素放大图,展示了 distort 为提供亚像素调整尺寸而添加的透明度…… |

  magick rose_distort_shift.png -crop 15x15+0+0 +repage \
          -scale 600%   rose_distort_shift_mag.png

[IM Output]
你可以看到顶部边缘保持锐利,而左侧(以及所有其他边缘)现在是半透明的。这正是关键所在。你拥有对调整尺寸以及结果图像最终亚像素位置的精确控制。而不仅仅是把调整尺寸后的图像量化适配到整数个像素。也就是说,distort 是对图像的精确重新缩放和定位,精确到像素的若干分之一,让你能够把它精确地装入其他图像中。在进行视频工作时,这一点会变得尤为重要,因为对嵌入图像不精确的调整尺寸会产生“跳动”效果。 | 技术上讲,图像调整尺寸是图像扭曲的一种简化形式,两者都是图像重采样的技术。它非常快速的两遍滤波技术,仅限于正交对齐的像素缩放,以及最终结果中整数个像素。
---|---
Affine、Transform 从 IM v6.4.2-8 起,与“[-transform](https://imagemagick.org/command-line-options/#transform)”或“[-draw](https://imagemagick.org/command-line-options/#draw)”操作符一起使用的较旧的“[-affine](https://imagemagick.org/command-line-options/#affine)”设置,提供了类似的自由形式调整尺寸能力。然而实际上它等价于用“[+distort](https://imagemagick.org/command-line-options/#distort)”配合“[AffineProjection](distorts.html#affine_projection)”扭曲方法来调用。因此前面所有的 Distort 注记都适用。它需要更多数学知识,使得典型用户难以使用。一般来说,你最好使用上面的扭曲方法,它提供了若干种指定要应用的仿射扭曲的替代方法。

Distort 与 Resize

如果你确实想在使用 DistortResize 之间做直接比较,你需要专门限制图像的扭曲,使其与你所比较的调整尺寸后的图像精确匹配。这不是一项简单的任务。为了让这变得更容易,IM v6.6.9-2 添加了一个特殊的 Resize 扭曲方法。例如,这里我先用快速的 Resize、再用 Distort 大幅放大内置的“rose:”……

  magick rose: -filter Lanczos -resize 300x rose_resize.png

  magick rose: -filter Lanczos -distort Resize 300x rose_distort.png

[IM Text]
Resize(Lanczos - Sinc) | [IM Text]
Distort(Lanczos - Jinc)
---|---

如果你沿玫瑰的底部边缘观察,你会看到 Distort 操作符 实际上产生了比 Resize 操作符 更好、更干净的结果。几乎没有放大图像时常见的 分块伪影。除了这条底部边缘外,图像的其余部分实际上完全相同,即使用“[flicker_cmp](../static/img/scripts/flicker_cmp)”脚本比较也是如此。然而请记住,DistortResize 慢得多,因为它使用一种更直接但复杂得多的 面积重采样 技术,没有 resize 所使用的两遍速度优化。 | _上面两张图像真正的区别在于,Distort 操作符 在其图像处理中使用了二维的 椭圆面积重采样 滤波方法(也称为柱面滤波或重采样)。这比本节中展示的所有其他调整尺寸方法所使用的一维两遍重采样方法更慢。这也是它在上面放大的玫瑰图像的对角底部边缘上产生更好结果的原因。它不局限于仅做水平和垂直滤波。

你可以在 振铃伪影 的示例中看到这对振铃的影响。

_
---|---


调整尺寸技术

带颜色空间校正的调整尺寸

虽然调整尺寸效果很好,但大多数人并没有正确使用它。甚至连我通常也只是按原样直接对图像调整尺寸,因此从技术上讲我调整图像尺寸的方式是不正确的。图像通常使用非线性的“sRGB”颜色空间,或带有伽马校正来存储。细节见 人类色彩感知。但调整尺寸(像大多数其他图像处理操作符一样)是一个数学上线性的处理器,它假定图像值直接表示线性的颜色亮度。“sRGB”颜色空间基本上包含一个大约 2.2 的伽马校正。实际上它比这更复杂,涉及两条独立的曲线。见 wikipedia, sRGBW3org, sRGB 互联网的默认颜色空间。从 6.7.5 版本起,ImageMagick 遵循这一约定,并将图像的默认颜色空间(至少对于大多数图像文件格式)定义为 sRGB。这意味着我们只需在做调整尺寸之前,使用“[-colorspace](https://imagemagick.org/command-line-options/#colorspace)”把图像转换到线性空间。 不推荐在低质量的 Q8 版本 IM(见质量)上使用颜色校正,因为这种低内存质量会带来精度损失。
NASA 图像“地球的城市灯光”是一个非常极端的案例,其中非线性颜色空间的影响对调整图像尺寸的结果有很大冲击。这里我们不做颜色空间校正直接调整图像尺寸……
  magick earth_lights_4800.tif -resize 500 earth_lights_direct.png

[IM Text]

而这里我们从非线性 sRGB 转换(magick)到线性 RGB,然后调整尺寸,再转换(magick)回去……

  magick earth_lights_4800.tif -colorspace RGB     -resize 500    \
          -colorspace sRGB  earth_lights_colorspace.png

[IM Text]

如你所见,图像中的“灯光”要明亮得多,因为它们没有那么严重地受源图像非线性颜色空间的影响。虽然大多数图像不会有上面这么大的影响,但它是存在的,而且会产生许多效应。从 sRGB 的非线性效应可以看到的主要效应是,较暗的颜色被保存为暗得多的值(以便在感知上更恰当)。但由于它们较暗,它们在数学上没有被正确处理,所以得到的 sRGB 图像比在像 RGB(或 LAB 或 LUV)这样的线性颜色空间中处理的图像更暗。另见 处理真实图像的颜色带伽马和颜色空间校正的绘图。同样正确的颜色空间处理也适用于 distort(椭圆滤镜)的使用、图像模糊,并且能对图像量化、抖动和有序抖动产生很大影响。这在重采样滤镜中有详细探讨。警告:RGB 颜色空间在涉及强烈原色变化(不仅是黑白之间)的边缘上可能产生裁剪问题。见下一节。 | |
---|---|---
在比 v6.7.5 更旧的 IM 版本中,默认输入颜色空间是“RGB”。“sRGB”颜色空间实际上意味着“从 sRGB 转换到线性 RGB”。结果是这两个标签被互换了!奇怪但真实。因此较旧版本的 ImageMagick 需要把上面那两个颜色空间名称互换来做颜色空间校正。像这样……

  magick earth_lights_4800.tif -colorspace sRGB \
          -resize 500  -colorspace RGB  earth_lights_colorspace.png

* 此示例已弃用 ***

注意“-colorspace RGB”操作其实并不需要,因为在保存为 PNG 图像文件格式时它会自动执行。上面的内容是从一场 IM 论坛讨论 正确的调整尺寸 中发展而来的。

带伽马校正的调整尺寸

这是仅使用伽马校正来正确调整图像尺寸的方法。

  magick earth_lights_4800.tif   -gamma 0.454545 \
          -resize 500    -gamma 2.2  earth_lights_gamma.png

[IM Text]

伽马逆操作“-gamma 0.454545”的一个替代方法是使用“-evaluate POW 2.2”。注意伽马校正只是与正确地把图像从/到 sRGB 颜色空间转换的一个粗略匹配,但它如此接近,以致于你很难看出颜色空间与伽马校正之间有任何区别。伽马校正也不会去摆弄 IMv7 的 RGB/sRGB 颜色空间设置,所以在确切版本未知时,它可能是更好的选择。你也许还想看看“[-auto-gamma](https://imagemagick.org/command-line-options/#auto-gamma)”操作符,它试图调整图像,以产生等量的明暗区域(假定图像处于线性颜色空间)。

在 LAB 颜色空间中调整尺寸

使用 sRGB、RGB 甚至 XYZ 颜色空间进行调整尺寸或任何图像处理的一个问题是,这 3 个颜色通道不仅表示颜色,也表示强度或亮度。这意味着如果一个通道变得扭曲(例如被裁剪),像素颜色也会变得扭曲,可能导致奇怪的外观。LAB 颜色空间不仅是一个线性颜色空间,而且被设计成强度(L 通道)与两个颜色通道(A 和 B 通道)相分离。这意味着如果任何一个通道被裁剪,它都不会产生颜色偏移。它还意味着通常没有任何通道实际上接近裁剪极限,除非你专门处理纯黑白图像,而这在现实生活的图像中并不常见。因此,通过使用 LAB 颜色空间处理图像,实际上效果更好,并避免了你在使用 RGB 或 XYZ 颜色空间时可能得到的裁剪和颜色偏移。 | _在 IM v6.7.8-2 之前,A 和 B 通道的 LAB 值使用有符号整数存储,存储在一个无符号整数的内存空间中。这在负值和正值之间造成了一个不连续,使得正常处理无法工作,只能进行图像格式转换。

这意味着在较旧版本的 IM 中,LAB 颜色空间的图像处理不起作用,尤其是当一个颜色同时涉及正值和负值时。也就是在处理在蓝-黄和红-绿之间变化的颜色时。

此版本之后,这些值在内部使用 50% 的偏置存储,消除了那个不连续,从而允许线性操作如预期工作。

_
---|---
对于涉及“锐化”重采样滤镜(非常常用)的调整尺寸,使用 Lab 颜色空间也会缓和极端的强度变化,那种变化可能在原色 RGB 中生成过强(且范围被裁剪)的 振铃伪影。例如……

  magick rose: -colorspace RGB  -filter Lanczos  -distort resize 300x \
          -colorspace sRGB rose_distort_rgb.png
  magick rose: -colorspace LAB  -filter Lanczos  -distort resize 300x \
          -colorspace sRGB rose_distort_lab.png

[IM Output]
原图 | | [IM Output]
RGB 颜色空间 | [IM Output]
LAB 颜色空间
---|---|---|---

如你所见,玫瑰的边缘在线性 RGB 颜色空间中被裁剪了,而在 LAB 颜色空间中没有被裁剪。在 RGB 颜色空间中,玫瑰的底部边缘出现了从近乎纯白到近乎纯红的颜色变化,导致“绿色”和“蓝色”通道发生强烈的(负向)变化。这产生了一个非常强的“负向波瓣”振铃效果,随后在 RGB 颜色空间中被裁剪。最终结果是由于滤镜的锐化效应而产生的严重颜色扭曲。在 LAB 颜色空间中,从白到红的转变在强度或颜色通道上都没有那么强烈,所以虽然我们在强度上得到了很好的锐化,但它和颜色通道都没有被裁剪,从而避免了颜色扭曲。结果是一张好得多的调整尺寸后的图像,带有来自滤镜的更恰当的锐化效果。仅仅通过把强度与颜色分离。

使用 LUV 颜色空间调整尺寸

从 IM v6.7.8-8 起,IM 还实现了一个密切相关的颜色空间 LUV。它们都被设计为感知均匀(线性),甚至共享相同的关键强度“L”或“明度(Lightness)”通道结果,尽管颜色通道的计算方式不同。主要区别在于 LUV 的颜色轴经过调整,以具有感知上相等的颜色增量(颜色差异),这导致其颜色尺度与 LAB 颜色空间略有不同,不过两者之间强度保持相同。见 Adams 色度价(chromatic valence)颜色空间。LAB 与 LUV 之间调整尺寸的结果实际上完全相同。

  magick rose: -colorspace LUV  -filter Lanczos  -distort resize 300x \
          -colorspace sRGB  rose_distort_luv.png

[IM Output]

关于这两个颜色空间的更多信息,见 颜色空间

使用不同颜色空间调整尺寸的小结

或者说,为什么不用 LAB 或 LUV 来调整尺寸?

嗯,因为就像 sRGB 一样,LAB 和 LUV 颜色空间是非线性的感知颜色空间!而那些数学运算本只应被应用于线性值。例如,这里是在“Lab”颜色空间中调整“地球的城市灯光”图像尺寸的结果。

  magick earth_lights_4800.tif -colorspace Lab     -resize 500    \
          -colorspace sRGB  earth_lights_lab.png

[IM Text]

结果实际上与你若直接在感知性的 sRGB 颜色空间中调整尺寸所得到的完全相同。但在感知颜色空间中调整尺寸真的是件坏事吗?这其实是个有争议的观点。看起来避免颜色通道裁剪是重要的,而颜色偏移(对不同颜色通道的不均等变化)则不那么重要。但话说回来,LAB 和 LUV 图像在感知上是线性的!因此,也许在一个线性-感知的颜色空间中混合颜色(这正是 重采样滤镜 实际所做的事情)实际上可能是件好事。最后还有一点,sRGB 只在原色分量上的强度方面是感知线性的。它在颜色上实际并非感知线性,所以它仍然是一个不适合做任何形式图像调整尺寸的颜色空间。Nicolas Robidoux 很好地总结道…… _一般来说,线性光颜色空间(线性 RGB 和 XYZ)会产生夸张的暗光晕,而“感知”颜色空间(sRGB、LAB、LUV)会产生夸张的亮光晕。

如果你思考一分钟,这就完全说得通了,因为感知颜色空间在强度谱较暗的一端塞入了大量比特,并“掏空”了较亮的一端,以模仿 HVS(人类视觉系统)。所以,1 单位的暗过冲在 sRGB 中比在线性 RGB 中走得“更近”,但 1 单位的亮过冲在线性 RGB 中比在 sRGB 中走得“更近”。

Sigmoid 化(见下文)平等地对待暗过冲和亮过冲,并通常抑制两者的极端。

_

使用 Sigmoidal 颜色空间调整尺寸

在 ImageMagick 讨论论坛上一场冗长的讨论 重采样滤镜光晕的 Sigmoid 最小化 中,开发出了一种新技术:与其试图在线性颜色空间中调整图像尺寸,不如使用 Sigmoidal 颜色修改操作符[-sigmoidal-contrast](https://imagemagick.org/command-line-options/#sigmoidal-contrast))在一个修改后的颜色空间中调整图像尺寸。这能减少可能沿非常锐利的边缘发展出的极端光晕或 振铃伪影 的裁剪。例如,这里是一系列“改进型”的调整尺寸技术,它们曾在数字图像处理论坛上被讨论过……

  magick rose: -colorspace RGB  -filter Lanczos  -resize 200x \
          -colorspace sRGB rose_resize_RGB.png
  magick rose: -colorspace RGB  -filter Lanczos  -distort resize 200x \
          -colorspace sRGB rose_distort_RGB.png
  magick rose: -colorspace RGB   +sigmoidal-contrast 6.5,50% \
          -filter Lanczos  -distort resize 200x \
          -sigmoidal-contrast 6.5,50% -colorspace sRGB  rose_sigmoidal_RGB.png

[IM Output]
Resize(普通线性) | [IM Output]
Distort(柱面) | [IM Output]
Sigmoidal 变体
---|---|---

本质上,上面最后那个示例所做的,是降低图像的对比度,把中间调灰度压缩到一个更紧的线性范围内,同时把极端值从裁剪边缘拉得更远,然后再调整尺寸。之后它再移除这种修改。这反过来弱化了颜色值的极端效应,同时仍然允许滤镜以线性方式处理中间调,从而减少颜色扭曲。在许多方面,这类似于在默认的非线性 sRGB 颜色空间中调整图像尺寸(这是一种太过常见的做法),但它对亮、暗振铃伪影都同样有效。也就是说,它在整个颜色值范围内是对称的,而在 sRGB 颜色空间中调整尺寸只从颜色范围较暗的低端起作用(上面的蓝色和绿色值)。也就是说,它是一种受控得多的技术。也有人评论说,这种 Sigmoid 变体可能只对放大效果良好。还可以为不同的图像尝试不同的 Sigmoidal 对比度强度值(上面是 6.5)。请记住,正如每一种调整尺寸技术一样,结果都是高度主观的,可能并不适合所有图像类型。 | _Sigmoidal 变换本质上生成了一种特殊的 DIY 非线性颜色空间,它建立在之前使用非线性感知颜色空间(sRGB)所获得的结果之上。

注意,在 RGB 颜色空间中用非线性颜色通道调整尺寸(扭曲)图像,可能在每个颜色通道中导致略微不同的结果。这会造成轻微的颜色偏移(与我们早先看到的颜色被裁剪相对)。

这只是非线性、颜色-强度通道混合的颜色空间(如 sRGB,或 Sigmoidal 颜色空间)才有的问题。

_
---|---

反锐化(USM)调整尺寸 —— Photoshop 调整尺寸技术

调整图像尺寸(无论缩小还是放大)常常会给图像添加一些模糊(模糊伪影)。因此许多人喜欢摆弄各种滤镜(见 重采样滤镜),试图让结果更锐利。但这会给图像结果添加其他 调整尺寸伪影。一种常用的方法是在调整尺寸后锐化图像。通常这是用特殊且名称怪异的 反锐化操作(Unsharp Operation) 来完成的,它包含更多用于控制结果质量的控制项。例如,让我们对非常模糊的“Spline”滤镜图像的结果做“反锐化”……

  magick logo: -filter spline -resize 150x logo_spline.png
  magick logo: -filter spline -resize 150x \
          -unsharp 0x1  logo_spline_unsharp.png

[IM Output]
Spline | | [IM Output]
反锐化后
---|---|---

如你所见,在调整尺寸后锐化图像改善了结果。尤其看星星和帽子的细节。你得到了一张非常好的锐利图像,没有任何混叠、振铃,甚至没有效果的变暗。虽然 Spline 滤镜 一开始并不是一个特别好的滤镜,但这种锐化(实际上是“反锐化”)方法对任何滤镜都有效。它还提供了更多控制项来微调结果。实际上这正是“photoshop”用来改善其调整尺寸后图像质量的做法,尽管我不知道它为 反锐化操作 使用了什么设置。一种称为 USM 的技术 “GIMP”反锐化的默认值(radius=6、amount=0.5、threshold=0)等价于“-unsharp 12x6+0.5+0”,这是正确的(除了忽略了 GIMP 将硬半径设为 sigma 两倍这一点)。然而请记住,在 ImageMagick 中你其实不需要指定核半径,所以“-unsharp 0x6+0.5+0”这样的值会更好。另见 IM 论坛主题 GIMP 中的反锐化参数。帖子 图像调整尺寸 建议对大于 500 像素的图像使用“-unsharp 0x0.75+0.75+0.008”。而一场 Open Photography Forum 讨论 用 ImageMagick 降采样 建议“-unsharp 1.5x1+0.7+0.02”。

调整尺寸以填充给定空间

基本上:把一张大图像调整尺寸以完全填满某个特定的图像尺寸,但裁剪掉图像中装不下的任何部分。 从 IM v6.3.8-3 起,新的调整尺寸标志 '^' 让你能在单次调整尺寸步骤中直接做到这一点。这些示例代表了一种可供较旧版本 IM 用户使用的替代方法。见上面的 调整尺寸填充标志
解决方案相当棘手,因为调整图像尺寸时用户通常的需求是把整张图像装入给定尺寸内。由于图像的宽高比被保留,这会在你试图填充的区域中留下额外的、未使用的空间。这里我们尝试把一张图像调整尺寸以填满一个 80x80 的方框。
  magick logo: -resize 80x80\> \
          -size 80x80 xc:blue +swap -gravity center  -composite \
          space_resize.jpg

[IM Output]
在上面我们添加了一块背景画布来填充调整尺寸方框中未使用的部分,以展示我们希望图像填满的空间,但它没有被填满,因为它保留了图像的宽高比。现在如果你所有的图像都是横向风格(它们的宽度大于高度),那么你当然可以直接把图像调整尺寸以适配该区域的高度或宽度,然后用“[-crop](https://imagemagick.org/command-line-options/#crop)”把图像裁剪到恰好合适。 |

  magick logo:    -resize x80  \
          -gravity center  -crop 80x80+0+0 +repage   space_crop.jpg

[IM Output]
问题在于,上面的做法只能处理横向风格的图像。如果图像是纵向风格(高度大于宽度),它会严重失败。当然这可以在脚本中解决,方法是先获取图像的尺寸,然后选择正确的方法把图像装入所需的空间。但更好的解决方案是让 IM 为所有图像完成全部工作。IM 内部的解决方案是分别对图像的每个维度进行调整尺寸来处理图像。然后从两个结果中挑选较大的图像。为了让这更容易,调整尺寸本身有一个内置的测试选项,它只在调整尺寸会使图像变大时才调整图像。这让我们能用一个非常巧妙的方案来解决问题。 |

  magick logo: \
          -resize x160 -resize '160x<'   -resize 50% \
          -gravity center  -crop 80x80+0+0 +repage  space_fill.jpg

[IM Output]
在上面,系列中的第二次调整尺寸只在第一次调整尺寸产生的宽度小于我们试图填充的区域时才进行调整尺寸。之所以选择这个特定的调整尺寸顺序(先高度,后宽度),是因为大多数图像是照片,通常水平方向更长。按上面的顺序,这种情况会导致第二次调整尺寸操作被跳过。如果你的图像更多是纵向图像(垂直方向更长),那么就更改参数,先按高度、再按宽度调整图像尺寸。例如…… |

  magick logo: \
          -resize 160x -resize 'x160<'   -resize 50% \
          -gravity center  -crop 80x80+0+0 +repage   space_fill_2.jpg

[IM Output]
这两个示例的结果应当非常相似,而且该命令对横向和纵向两种风格的图像都有效,尽管它对其中一种效果更好。这种方法最大的问题是图像现在被调整尺寸 2 到 3 次,在最终结果中产生额外的模糊和其他可能的伪影。为了减少这一点,初始的几次调整尺寸是在最终尺寸的两倍大小上进行的,这假定原图至少是最终所需结果尺寸的 3 倍或更大。对于缩略图制作来说这不是问题,但需要记在心上。

调整线条画的尺寸

对含有细线的图像做强烈的调整尺寸可能代表一个大问题…… 把图像调整到非常小的缩略图,会导致那些只有几像素宽的细线褪色并消失到背景中。这可能糟糕到我曾见过一张线条画的缩略图看起来完全空白!也就是说,原图的每一处细节都“消失”了,使缩略图相当无用。如果这是个问题,有一些技术可以帮上忙……

  • 调整尺寸后再调整对比度,使线条更明显。不过这会让线条更加混叠(阶梯状)。它在这种技术能用到什么程度上也有限制。
  • 对图像进行模糊和阈值化(一种与形态学“膨胀(dialate)”或“腐蚀(erode)”非常相似的方法),从而使单像素线条变粗约 300%。这样在调整尺寸为原来的 1/3 之后,图像会变小,但线条会保持和之前一样强烈、可见。
  • 使用 增粗形态学(Thicken Morphology) 技术增粗线条。你也许想分阶段做调整尺寸,每次把图像增粗并调整尺寸 50%,直到达到最终尺寸。不过随着线条之间的间距缩小,你可能会发现最终得到的更像是一个“团块”而不是线条画。也就是说,你可能会得到相反的问题。然而调整增粗与调整尺寸的比例应当能产生可接受的结果。
  • 把图像中的线条边缘与纯色区域分离开,用不同的方法分别调整它们的尺寸(线条使用上面的方法)。之后这两部分可以重新合并到一起,让你能够保留图像的线条边缘。这实际上会重现你在调整矢量图像尺寸时常常得到的效果。
  • 把图像转换为矢量图像,然后再调整尺寸。这可能很棘手,但也能为调整线条画的尺寸产生尽可能最好的结果,带有完美的抗锯齿(锐利)边缘和清晰的图像。

如果你想出了其他有效调整线条画尺寸的方法,或试过上面的某些技术,请让我(以及其他 IM 用户)知道。