我正在调整电影图谱的大小。如果您不知道,它们是GIF,其中只有一部分图像是动画的,而普通的GIF则是整个图像的动画。这是node.js示例:
// ![http://i.imgur.com/Qb1m0.gif][1]
var gm = require('gm')
var file = 'Qb1m0.gif',
frags = file.split('.')
gm(file)
//.noProfile()
//.quality(80)
.resize(200, 200)
.write(frags[0] + '_200.' + frags[1], function(err) {
if (err) console.error(err)
})
// Result:
// ![http://i.imgur.com/eFqak.gif][2]
等效的cmd行代码是:
gm convert Qb1m0.gif -resize 200x200 cinema_200.gif
知道发生了什么事吗?
答案 0 :(得分:19)
我比ImageMagick更了解ImageMagick。对于ImageMagick,以下陈述适用:
如果GIF包含透明度,则几乎不可能使用简单的命令行(例如您给出的那个)直接调整动画 GIF的大小。
如果动画GIF不包含透明度,甚至很难做到这一点。
我认为这对于GraphicsMagick来说确实如此。
如果您使用identify
查看原始GIF,则会看到并非每个框架都具有相同的尺寸:
identify Qb1m0.gif Qb1m0.gif[1] GIF 720x416 720x416+0+0 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[1] GIF 471x122 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[2] GIF 471x121 720x416+160+76 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[3] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[4] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[5] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[6] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[7] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[8] GIF 471x122 720x416+160+76 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[9] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.009 Qb1m0.gif[10] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.000 Qb1m0.gif[11] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.000 Qb1m0.gif[12] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.000 Qb1m0.gif[13] GIF 471x122 720x416+160+76 8-bit PseudoClass 256c 920KB 0.000u 0:00.000 Qb1m0.gif[14] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.000 Qb1m0.gif[15] GIF 471x123 720x416+160+75 8-bit PseudoClass 256c 920KB 0.000u 0:00.000
尺寸的这些变化是 frame 优化动画GIF的结果,以减小文件大小。
还有其他优化方法可以减少使用的颜色数量。这两种类型的优化都不能与-resize
操作完美结合。
-resize
专为单个图像而设计,并使得到的单个图像看起来尽可能好。这通常会为图像添加新的颜色值。这与GIF的设计相矛盾:使用严格限制的颜色表(最多256种颜色)。在动画序列中,下一个图像/帧的-resize
可能会产生与前一个产生的颜色表完全不同的颜色表 - 但是对于一个运行良好的动画,您需要跨所有帧的共同颜色表。
-resize
完全独立于其他图像处理每个帧图像,并没有考虑“帧优化”(它们倾向于为放置在公共区域上的每个帧创建不同的宽度+高度画布有自己的偏移量。)
因此,调整大小的图像远非理想,无法保存单个图像的有限GIF文件格式,更不用说动画GIF的多个帧。结果是调整大小的图像中的重颜色减少。
然后存在透明度问题:大多数动画GIF确实大量使用透明度。透明度经常用于甚至实现压缩优化,通常图像的外观根本不需要透明度。
在这种情况下会发生这样的情况:-resize
在叠加图像中创建半透明像素。当图像保存回GIF文件格式时,这些像素将转换为完全透明或完全不透明:两者都会对生成的动画产生严重的颜色失真,远离原始颜色。
通常,调整动画GIF大小的最佳步骤是:
合并(取消优化)动画。这将为动画的所有帧创建相同大小的单个图像。
为动画提供完整的GIF优化序列:不仅适用于 frame 优化,还适用于 color 优化。
要运行'简单'调整大小命令仍然试试运气,你可以试试这个:
convert \
http://i.imgur.com/Qb1m0.gif \
-coalesce \
-resize 200x200 \
cinema_200.gif
<强>结果:强>
此命令可解决帧优化问题。它会纠正由此造成的问题,但会增加文件大小。
然而,当涉及到边缘时,它仍然可能会显示“阶梯”伪影,因为调整大小的帧将会出现可怕的混淆。这是因为抗锯齿需要边缘周围的半透明颜色,但GIF无法保存-resize
运算符生成的半透明颜色。
答案 1 :(得分:0)
您也可以尝试添加-layers optimize
更多细节
https://imagemagick.org/script/command-line-options.php#layers
答案 2 :(得分:0)
使用gifsicle工具也与ImageMagick解决方案无关,它产生的gif较小,并且没有任何闪烁的问题,也没有特殊的命令行参数,因此非常简单,也可以正常工作快点。像这样使用它:
gifsicle --scale 0.25 -i input.gif > output.gif
或
gifsicle --resize 24x24 -i input.gif > output.gif