调整电影画照片大小时出现的问题(动态GIF图像)

8

我在调整cinemagraphs大小时遇到了问题。如果您不知道,它们是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]

对应的命令行代码如下:

gm convert Qb1m0.gif -resize 200x200 cinema_200.gif

了解发生了什么?

原始动画 GIF:

原始

调整大小后的动画 GIF:

调整大小后

3个回答

20
我比较熟悉ImageMagick而不是GraphicsMagick。对于ImageMagick,以下声明适用:
- 如果GIF动画包含透明度,则使用简单的命令行(如您提供的命令)直接调整大小几乎是不可能的。 - 即使动画GIF没有包含透明度,也很难做到这一点。我认为GraphicsMagick的情况也是如此。
背景解释
如果用identify查看原始GIF,您会发现每个帧的尺寸并不相同:
这些尺寸变化是由于优化帧导致的,以减小文件大小。还有其他优化在起作用,这些优化确实减少了使用的颜色数量。这两种类型的优化与-resize操作结合使用效果不佳。 -resize是为单个图像设计的,并且使得生成的单个图像看起来尽可能好。这经常会向图像添加新的颜色值。这与GIF的设计相矛盾:使用严格限制的颜色表(最多256种颜色)。在动画序列中,下一个图像/帧的-resize可能会产生一个完全不同的颜色表,而不是上一个 - 但对于一个正常工作的动画,你需要在所有帧之间共享一个公共的颜色表。 -resize 完全独立于其他图像处理每个帧,不考虑'帧优化'(倾向于在公共画布上放置自己的偏移量为每个帧创建不同的宽度+高度)。
因此,调整大小后的图像远非理想的保存到单个图像的受限GIF文件格式,更不用说多帧动画了。调整大小后的图像进行了大量的颜色减少。
然后是透明度问题:大多数动画GIF确实广泛使用透明度。通常使用透明度甚至可以实现压缩优化,而正常情况下该图像的外观根本不需要透明度。
在这种情况下会发生以下情况: -resize会在叠加图像中创建半透明像素。当将这些图像保存回GIF文件格式时,这些像素将转换为完全透明或完全不透明:两者都会导致结果动画中的严重颜色失真,远离原始颜色。
一般程序
调整大小动画GIF的最佳步骤通常如下:
1. 将动画合并(去除优化)。这将为动画的所有帧创建相同大小的单独图像。 2. 对动画进行完整的GIF优化序列:不仅针对帧优化,还包括颜色优化。
“简单”命令
如果您仍想尝试运行“简单”调整大小命令,则可以尝试这个:
convert                        \
  http://i.imgur.com/Qb1m0.gif \
 -coalesce                     \
 -resize 200x200               \
  cinema_200.gif

结果:

 结果

这个命令可以解决帧优化问题。尽管会增加文件大小,但会纠正因此导致的问题。

但是,当涉及到边缘时,它仍可能显示“阶梯状”伪影,因为调整大小后的帧将出现可怕的锯齿状。这是因为抗锯齿需要在边缘周围生成半透明颜色,但GIF无法保存由于-resize操作符生成的半透明颜色。


谢谢。我想我会忽略调整cinemagraphs的大小。从第三个和第四个参数比较尺寸是否是检测cinemagraph的好方法?Qb1m0.gif[1] GIF 471x122 720x416+160+75 - Jonathan Ong
您可以运行 identify -format '%W x %H\n' your.gif 直接查询 GIF 中每个帧的宽度和高度。但是可能存在没有不同帧大小的 cinemagraphs。我认为最“可靠”的问题是:“(1)这是一个 GIF 吗?”“(2)它是否包含多个帧?” 如果两个答案都是“是”,那么您很可能拥有一个动画 GIF。 - Kurt Pfeifle

0

0

还有一种与ImageMagick无关的非常好的解决方案,使用gifsicle工具,它可以生成更小的gif文件,并且没有任何闪烁问题,也没有特殊的命令行参数,因此非常简单,而且速度更快。像这样使用:

gifsicle --scale 0.25 -i input.gif > output.gif 

或者

gifsicle --resize 24x24 -i input.gif > output.gif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接