Delphi TGIFImage 与某些 GIF 查看器的动画问题

2023-11-24

我发现使用 Delphi 2009 创建的动画 GIFTGIFImage有时无法正确播放someGIF 观众。问题是动画过早地重新启动。

考虑以下示例:

program GIFAnomaly;

{$APPTYPE CONSOLE}

uses
  Windows, Types, Classes, SysUtils, Graphics, GIFImg;

var
  g: TGIFImage;
  bm: TBitmap;

procedure MakeFrame(n: integer);
var
  x: Integer;
  y: Integer;
begin
  for x := 0 to 256 - 1 do
    for y := 0 to 256 - 1 do
      bm.Canvas.Pixels[x, y] := RGB((x + n) mod 255,
        (x + y - 2*n) mod 255, (x*y*n div 500) mod 255);
end;

var
  i: integer;

begin

  bm := TBitmap.Create;
  bm.SetSize(256, 256);

  g := TGIFImage.Create;
  g.Animate := true;
  for i := 0 to 499 do
  begin
    MakeFrame(i);
    TGIFGraphicControlExtension.Create(g.Add(bm)).Delay := 3;
    Writeln('Creating frame ', i+1, ' of 500.');
  end;
  TGIFAppExtNSLoop.Create(g.Images.Frames[0]).Loops := 0;

  g.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\test.gif');


end.

(这是我能找到的最简单的例子来说明这个问题。)

输出是一个相当大的动画 GIF。在 Internet Explorer 11 中,整个 15 秒的“电影”可以正常播放,但在 Google Chrome 中,“电影”仅在大约四秒后就过早重新启动。

为什么是这样?

  1. 输出的 GIF 文件有问题吗?
  2. 如果是的话,是我上面的代码有问题,还是有问题GIFImg?
  3. 如果不是,查看器中问题的本质是什么?有多少观众有这个问题?有没有办法在 GIF 创建过程中“避免”这个问题?

为了 SO 用户的利益,上面的代码是一个最小的工作示例。当然,当我发现这个问题时,我并没有创造这些迷幻的模式。相反,我正在开发 Lorenz 系统模拟器,并制作了这个 GIF 动画,它可以在 IE 中播放,但不能在 Chrome 中播放:

Sample GIF animation displaying the issue

在 Internet Explorer 11 中,模型在动画重新启动之前旋转 360 度。在 Google Chrome 中,动画仅在大约 20 度后就过早重新启动。

  • 洛伦兹图像works在 Internet Explorer 11.0.9600.17239、GIMP 2.8.0、Opera 12.16 中
  • 洛伦兹图像不起作用在谷歌浏览器 36.0.1985.143 m、火狐浏览器 26.0、27.0.1、31.0 中。

如果我在 GIMP 中打开一个“有问题”的 GIF 并让 GIMP(重新)将其另存为动画 GIF,则结果在每个查看器中都有效。以下是洛伦兹动画的 GIMPed 版本:

Sample GIF animation that has been GIMPed

使用十六进制编辑器比较两个文件,并使用维基百科文章作为参考,例如,“NETSCAPE”字符串似乎位于原始(未GIMPed)版本中的错误位置。有点奇怪的是,即使我设置了width and height对于 GIF 图像,逻辑屏幕描述符中的相应值不存在。


这是 TGIFImage 的 LZW 编码器中的一个错误。

在某些非常罕见的情况下,LZW 编码器将在 LZW 流末尾输出额外的零字节。由于 LZW 结束块标记也是一个零字节,严格的 GIF 阅读器可能会对此感到窒息或将其解释为 GIF 的结束(尽管文件结束标记是 $3B)。

一些 GIF 阅读器能够处理这个问题的原因可能是很多年前就有这个问题的 GIF 很常见。显然 TGIF Image 并不是唯一犯这个错误的库。

要解决该问题,请进行以下修改gifimg.pas(更改标记为*):

procedure TGIFWriter.FlushBuffer;
begin
  if (FNeedsFlush) then
  begin
    FBuffer[0] := Byte(FBufferCount-1); // Block size excluding the count
    Stream.WriteBuffer(FBuffer, FBufferCount);
    FBufferCount := 1; // Reserve first byte of buffer for length
    FNeedsFlush := False; // *** Add this ***
  end;
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi TGIFImage 与某些 GIF 查看器的动画问题 的相关文章

  • 在 Outlook 中创建带有附件的邮件并显示它

    我想在 Outlook 中创建一封带有附件的邮件并在发送之前显示它 但我想我已经尝试了几乎在网上找到的所有示例 但没有任何运气 我可以使用 Indy 但我非常想使用 Outlook 来确保邮件正确 因为它是用于商业用途 函数的任何输入 该函
  • Winform 没有.NET 框架?

    我必须创建一些表单并将其作为直接 EXE 提供 而不是安装程序 它安装 NET 框架 最终用户对此不满意 他们想要可以直接打开和工作的东西 我知道它可以作为网络完成 但我正在寻找 winforms 吗 请建议哪种工具 技术可以处理这个问题
  • 从单个应用程序中的多个线程调用 dll 函数是否安全?

    我正在 Delphi 2009 中编写一个服务器应用程序 它实现了多种类型的身份验证 每种身份验证方法都存储在单独的 dll 中 第一次使用身份验证方法时 会加载适当的 dll 仅当应用程序关闭时 DLL 才会被释放 在服务器线程 连接 之
  • 为应用程序启用主题

    我有一个旧的应用程序 在Win XP中的delphi 7中启动 现在我正在使用delphi 2009 win Vista 如果我开始一个新项目 所有按钮都有一个圆形边缘 但在我的旧应用程序中 所有按钮都有 方形 形状的外观 有什么设置我错过
  • 使用 StretchDIBits 使用 Delphi 6 处理条形码图像 - 输出中缺少条形线

    我的应用程序是在 Delphi 6 中开发的 由于后台处理和大量数据 它消耗大约 60MB 120MB 物理内存 这是一个资源密集型应用程序 该应用程序的功能之一是在进行某些处理后创建条形码图像 如果用户继续生成条形码 那么至少十分之一的条
  • 获取字符、整数和日期字段的字段 oldValue 和 newValue

    我试图只保留表更改的历史记录 所以我想获取一个字段在更改为oldValue之前的值 然后获取它更改为newValue的值 两个值都应转换为字符串 因此 这是该表的一个示例 PartNumber Description 12345 Test
  • 动画 .GIF 在 IE 10 中不起作用

    我创建了一些动画 gif 它们在 Firefox 和 Chrome 中运行良好 但在 IE 10 中运行不佳 有什么方法可以解决这个问题吗 只需尝试在各种浏览器中查看下图即可 据我所知 问题不在于您的页面或动画 GIF 本身 这是客户端IE
  • 如何逐步绘制矢量路径? (拉斐尔.js)

    如何逐步动画化矢量路径 就像它被绘制一样 换句话说 慢慢地逐像素地显示路径 我在用着Rapha l js but如果您的答案不是特定于库的 例如可能有一些通用的编程模式可以完成此类事情 我对矢量动画相当陌生 欢迎 使用直线路径很容易做到 就
  • Delphi 的免费加密库 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在为 Delphi 2010 寻找一个免费且最新的加密库 该库实现 RSA 和 AES Rijnda
  • 如何重新启动/重置 Jquery 动画

    如何在 jquery 中重置动画 例如 CSS block position absolute top 0 left 0 JS block animate left 50 top 50 如果我做 block stop 动画将停止 但我怎样才
  • css动画移动元素位置

    我的 CSS 动画有这个问题 我有一个元素位置绝对居中于页面中间 当我放置动画时 它会向右移动 当动画完成时 它会移回到页面中间 这是代码 keyframes motto from opacity 0 transform translate
  • Delphi 2007 中的 HelpInsight 文档

    我正在使用 D2007 并尝试使用 HelpInsight 功能 自 D2005 起提供 来记录我的源代码 我主要对让 HelpInsight 工具提示正常工作感兴趣 通过各种网上冲浪和实验 我发现了以下内容 使用三斜杠 注释样式比其他记录
  • 如何读取注册表项的默认值

    我有一个 Delphi XE2 项目来使用注册表项进行某些操作 所以我定义了以下代码 procedure TMainForm BitBtn01Click Sender TObject var RegistryEntry TRegistry
  • 在 D3 中在外部加载的 svg 图形上绘图

    我已经从 svg 文件加载了外部图形 我想尝试在其上绘图 但不知道如何操作 我的简单 d3 代码在这里
  • 如何消除批处理文件动画中的闪烁? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 因此 我一直在批量制作一个假 GUI 以作为我正在做的 YouTube 评论的结尾 它基本上是一堆方框
  • 如何使用 jQuery 在第二次单击时反转 CSS 动画

    我制作了以下菜单图标 CSS 动画 当我点击它时会触发它 当我使用 jQuery 第二次单击它时 我想使其反向动画 path1 stroke dasharray 33px stroke dashoffset 33px animation l
  • 在 Swift 中将 gif 保存到 iOS 照片库

    我正在尝试保存位于已使用 Regift 代码创建的临时文件中的 GIF 图像 Regift https github com matthewpalmer Regift https github com matthewpalmer Regif
  • 使用 TStringList 的分隔符解析字符串,似乎也解析空格(Delphi)

    我有一个简单的字符串 由某个字符分隔 比如说逗号 我应该能够创建一个 TStringList 并将其分隔符设置为逗号 然后将 DelimitedText 设置为我想要解析的文本 并且应该自动解析它 问题是 当我查看输出时 它还包含空格作为分
  • Delphi 5 的哈希表实现 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您知道 Delphi 5 的良好且免费的哈希表实现吗 我需要在哈希表中组织大量数据 并且我有点担心在网
  • Delphi 流畅的界面

    使用上有什么优点和缺点流畅的界面 http en wikipedia org wiki Fluent interface在德尔福 流畅的界面应该会增加可读性 但我对此有点怀疑one包含很多链式方法的长 LOC 是否存在编译器问题 是否存在任

随机推荐

  • C# 中的 HttpWebRequest 不适用于 .net 4.5

    我正在开发一个 C 项目 该项目将 xml 发送到服务器并接收 xml 作为响应 安装 Net Framework 4 0 后 可以正常工作 安装 Net Framework 4 5 后 它会抛出此异常 System NullReferen
  • 是否可以在 Rails 中创建两个日期之间的月份列表

    我正在尝试创建一个页面来显示每个月的链接列表 按年份分组 月份必须位于 今天 和 首次输入的日期 这两个日期之间 我在砖墙上 我不知道如何创建它 任何帮助将不胜感激 问候 亚当 只需将您想要的内容放入范围循环中并使用 Date MONTHN
  • Flutter:将 Widget 的边缘与第二个 Widget 重叠

    我想将一个小部件的底部边缘与另一个小部件重叠 使其看起来像这样 我正在使用堆栈将箭头按钮放置在卡片上 目前我只是设置了位置 上面有一个看不见的框 问题是这种方法仅适用于确切的分辨率 它应该与屏幕尺寸无关 小部件的必要代码 Stack chi
  • 增加 catalina.bat 文件中堆大小的最佳方法

    我在 windows xp 上有 tomcat 6 服务器 并且我通过控制台启动 tomcat 即使用startup bat AFAIK catalina bat文件适用于 Windows 因此我正在更改 bat 文件以进行内存管理 我没有
  • 如何调用Web服务方法进行测试,例如从浏览器

    有一个 dll webservice 用 Delphi 制作 有一个名为List它返回字符串列表 宽字符串 是否有任何方法可以调用该服务而无需编写客户端应用程序来使用它 Ex http misitio com 8080 miwebservi
  • Emacs 24内置cedet功能亮点

    我想去掉上面的下划线功能 例如 如上面 void 的屏幕截图所示 http cedet sourceforge net img gen semantic ia complete menu png 我在文档中找不到任何明显的内容 但哎呀 我什
  • 将行替换为空格,将反斜杠替换为包含空格的字符串

    我想替换以下行 memory 20g with memory 100g 实际上它应该替换之后的任何数字 memory 以下是我所拥有的 但无法获得预期的结果 sed i E s b memory memroy 100g g a txt 您不
  • 如何在代码外部(即 XML 文件中)定义 AutoMapper 映射,或使用不同的方法来实现完全可配置的对象映射?

    EDIT 最初我打算使用 AutoMapper 来实现我的目标 但我必须知道 AutoMapper 并不是这样工作的 它使您可以创建配置文件 但在我的情况下 完全可配置 我需要为每个参数组合一个配置文件 所以我想出了一种自己的方法 请参阅答
  • AngularJS - jQuery UI - 绑定问题

    我目前正在将一个大型应用程序移植到一个基于 HTML5 的 Web 应用程序 我已经开始在 AngularJS 中构建该应用程序并享受 AngularJS 框架的强大功能 目前我遇到一个问题 我有一个指令为我提供了 jQuery Datep
  • 如何让 Python / PostgreSQL 更快?

    现在我有一个日志解析器读取 515mb 的纯文本文件 过去 4 年里每天的一个文件 我的代码目前是这样的 http gist github com 12978 我已经使用了 psyco 如代码中所示 并且我也在编译它并使用编译后的版本 它每
  • 如何将 tail -f 通过管道传输到 awk 中

    我正在尝试设置一个脚本 当日志文件中出现某个字符串时 会生成警报 已有的解决方案每分钟一次 grep 整个日志文件 并计算字符串出现的频率 使用日志行的时间戳仅计算前一分钟的出现次数 我认为用尾巴来做这件事会更有效 所以我尝试了以下方法作为
  • ASP.NET中如何在Web表单之间传递信息

    如何在asp net中将一些信息从一个Web表单发送到另一个Web表单 第一个网页表单是HumanList aspx显示a中的人类列表GridView成分 当用户单击编辑链接时 我想传递 humanID 人类记录 ID 的值 HumanLi
  • Google 自动完成教程为 swift 放置 api

    我想要一个自动完成文本字段 可以像 Android 一样自动完成位置 https developers google com places training autocomplete android 有谁知道我在哪里可以找到这方面的教程或示
  • 使用 youtube 播放器 api 在后台播放 Youtube 视频

    我已经使用成功播放了 YouTube 视频youtube player api 但我需要在按下后退按钮时在后台运行它 我用谷歌搜索了很多 但没有找到任何结果请帮助我实现这一目标 提前致谢 这是我的代码 public class Fullsc
  • 传递 null 时选择哪个构造函数?

    在下面的示例中 我有 2 个构造函数 一个采用 String 另一个采用自定义对象 在此自定义对象上存在一个方法 getId 该方法返回一个字符串 public class ConstructorTest private String pr
  • Ruby 中什么时候需要 do 关键字?

    例如 是否存在do下面的代码对程序的行为有什么影响 while true do puts Hi break end while true puts Hi break end 根据Ruby 编程语言本书第 5 2 1 节 The do中的关键
  • 如何在 SQL Server 中使用前导通配符全文搜索?

    Note I am使用 SQL 的全文搜索功能 CONTAINS 子句和所有 是全文中的通配符 仅适用于 LIKE 子句 我现在在几个地方读到 MS SQL 不支持 前导通配符 搜索 例如使用 overflow 来匹配 stackoverf
  • MongoDB v2.4.9 按布尔字段排序

    如何根据布尔字段对查询结果进行排序 考虑以下集合 id ObjectId name John isFoo true id ObjectId name Jim isFoo false id ObjectId name Joel isFoo f
  • 兼容 Nexus 的存储库,用于获取节点和 npm 安装程序

    我正在寻找一个符合 nexus 标准的存储库 我可以在其中获取节点安装程序 一个符合 nexus 标准的替代品 http nodejs org dist 语境 在java环境中 我们的构建是由maven处理的 最近我们添加了一个 javas
  • Delphi TGIFImage 与某些 GIF 查看器的动画问题

    我发现使用 Delphi 2009 创建的动画 GIFTGIFImage有时无法正确播放someGIF 观众 问题是动画过早地重新启动 考虑以下示例 program GIFAnomaly APPTYPE CONSOLE uses Windo