【问题标题】:GIF Image getting distorted on interlacingGIF 图像在隔行扫描时失真
【发布时间】:2016-02-09 05:25:21
【问题描述】:

我有一些使用 Imagemagick 及其交错操作转换的图像。这些是动画 GIF 图像。问题是,在转换时,图像已经变形,我没有原始图像,因为之前的开发人员做了很棒的事情。 GIF 不再具有动画效果,并且每帧都有 4 个相同帧的副本,但尺寸会逐渐减小。我之前在 Imagemagick 上工作不多。

有什么方法可以从变形的版本中恢复原始图像?

使用的命令是:

convert <old-file.gif> -interlace plane <new-file.gif>

谢谢

【问题讨论】:

  • 添加图像示例,这样我们就可以查看它是否真的错了(看看它是否包含它应该包含的内容)...这也是 GIF87a 或 GIF89a ...你在预览什么?你试过不同的 GIF 查看器吗?
  • @Spektre 感谢您的回复。我已经添加了图片。
  • 添加了修复的图像和一些链接+信息来回答。如果您也需要辅助扩展提要,那么您需要自己处理它。时间也可能与原来的有点偏差...

标签: animation imagemagick gif imagemagick-convert interlacing


【解决方案1】:

interlaced GIF 图像存储为 4 个分离的图像

  1. 包含每 8 行图像(大小的 1/8)
  2. 包含每个缺失的第 4 行图像(大小的 1/8)
  3. 包含每条缺失的偶数行图像(大小的 1/4)
  4. 包含图像的每一个奇数行(大小的 1/2)

这样做是为了在通过缓慢的 Internet 连接加载时可以看到图像...随着每个新块增加细节...

因此,如果您的图像看起来像 4 个非常相似的图像,那么结果是可以的,您只是错误地解码它或者 GIF 没有设置隔行扫描标志。

如果您的文件不再包含动画帧,那么您就不走运了,但是如果它们存在并且没有渲染,请检查文件的 GIF 结尾是否放错了位置,或者检查它们可能被搞砸的标志......有你尝试了不同的 GIF 查看器(有些是错误的)

解码 GIF 后[Edit1]

您获得了 GIF89a,但您在每一帧中都缺少交错标志。所以图像是正确隔行扫描的,但观众认为它根本不是隔行扫描的……您需要在每个帧头中标记隔行扫描标志。

struct _img // this is image frame header
    {
    // Logical Image Descriptor
    BYTE Separator;         /* Image Descriptor identifier 0x2C */
    WORD x0;                /* X position of image on the display */
    WORD y0;                /* Y position of image on the display */
    WORD xs;                /* Width of the image in pixels */
    WORD ys;                /* Height of the image in pixels */
    BYTE Packed;            /* Image and Color Table Data Information */
    } img;

img.Packed|=64; // this will set the interlaced flag

为此,您需要解码/流式复制 GIF,这并不像听起来那么容易。

见:

这里是帧复制 + 去隔行 + 隔行编码的结果(跳过控制/信息/辅助馈送...)

【讨论】:

  • 非常感谢。我已经开始编写一个脚本来执行此操作,因为我有数百个这样的图像。所以,我必须从图像中读取数据字节,并尝试在每一帧上找到交错位并翻转它。如果我错了,请纠正我。
  • @Nerve 是的,完全正确...查看链接 [如何在 GIF 图像中查找图像块从哪里开始?] 从我的回答中,有我用于处理 GIF 的 C++ 源...跨度>
  • 我已经能够找到第一帧的隔行扫描位。在此之后,第一帧变得完美。但是,我仍然无法为其他框架找到它们。我无法确定如何在图像数据块中找到帧。你能帮忙吗?
  • @Nerve 您需要处理/skp 类似于跳过扩展块的帧 LZW 数据,并且当检测到第 ecnd 帧时,以与第一帧相同的方式搜索下一帧(除了不再有全局调色板)。所有块的第一个字节都是块长度,然后是数据,所以跳过它......如果找到终止块(大小 = 0),你就在图像帧的末尾。如果我没记错的话,在第一块图像数据之前有 1 BYTE 告诉有多少位开始。
  • 顺便说一句,您的图像中有一半以上是辅助控制提要,我在答案中发布的已修复没有它们(略小于原始 gif 大小的一半)...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 2021-07-09
  • 2018-06-23
  • 2021-08-27
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
相关资源
最近更新 更多