使用TGIFImage重建和保存Gif的问题(Issue with rebuilding and saving Gif's using TGIFImage)

我还有另一个关于Delphi XE附带的GifImage.pas的问题。 我问的问题与之前提出的问题有关: TGifImage透明度问题

上一个问题的问题通过使用TGifRenderer从Gif文件中显示正确的帧来解决,该文件非常适合加载。

但现在我需要做相反的事情,我需要重建并从一系列位图中保存一个新的Gif。 但是当我保存时,输出Gif文件绘制不正确 - 就像之前一样。

我不确定我是否需要再次使用TGIfRenderer,因为我所做的只是添加位图和打包然后保存Gif。

要查看我面临的确切问题,请继续阅读(对于长篇文章提前道歉!)

首先将这些位图保存到新的示例项目文件夹:

注意:这些图像最初是位图,但StackOverflow似乎已将它们转换为PNG,因此您可能需要复制到Paint并再次保存。

现在从新项目中粘贴以下代码:

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, GifImg, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Bmp: TBitmap; Gif: TGIFImage; begin Bmp := TBitmap.Create; Gif := TGIFImage.Create; try Bmp.LoadFromFile('img0.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); Bmp.LoadFromFile('img1.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); Bmp.LoadFromFile('img2.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); Bmp.LoadFromFile('img3.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); // add netscape loop if we want animation to keep repeating TGIFAppExtNSLoop.Create(Gif.Images.Frames[0]).Loops := 0; Gif.Pack; Gif.SaveToFile('test.gif'); finally Bmp.Free; Gif.Free; end; end; end.

确保保存的位图与项目的exe文件位于同一文件夹中(或更改文件名路径),然后运行项目以创建输出gif。

保存的输出不正确。 从上面保存的企鹅位图中,我得到了这个保存的Gif:

你可以看到框架相互重叠或者正在发生什么样的事情! 这个gif文件的源代码可以在这里找到: http : //www.animated-gifs.org.uk/agif/ani02.gif

我没有使用Gif中的所有帧,因为有很多帧,但你可以看到它在动画时应该如何工作。

请注意,每个gif都不会发生这种情况,只有少数几个像这样保存。 另一个例子是尝试这些位图而不是企鹅:

结果是:

应该是(注意飞机上的火焰):

简单地说,我需要从一系列位图中保存一个Gif,就像它们打开时的样子一样。 您可以从上面的示例位图中看到与实际图像数据没有不一致,因此这让我相信它与它们如何添加到gif有关。

如果我确实需要再次使用TGIfRenderer,我不确定如何实现保存,我一直认为它仅用于加载?

这是我得到的无法解决的问题之一。 我一直试图改变透明度,颜色和模式等,但我似乎无法弄明白。

I have yet another problem regarding GifImage.pas that is included with Delphi XE. The issue I have sort of relates to a previous question I asked: TGifImage Transparency Issue

The problem from the previous question above was solved by using the TGifRenderer to display the correct frames from a Gif file which worked perfectly for loading.

But now I need to do the opposite, I need to rebuild and save a new Gif from a series of bitmaps. But when I save, the output Gif file draws incorrectly - just like before.

I am not sure if I need TGIfRenderer again or not because all I am doing is adding bitmaps and packing then saving the Gif.

To see the exact problem I am facing, please carry on reading (apologies in advance for the long post!)

First save these bitmaps to a new sample project folder:

NOTE: These images were originally bitmaps but StackOverflow seems to have converted them to PNG so you might need to copy into Paint and save again.

Now from a new project, paste the following code:

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, GifImg, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Bmp: TBitmap; Gif: TGIFImage; begin Bmp := TBitmap.Create; Gif := TGIFImage.Create; try Bmp.LoadFromFile('img0.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); Bmp.LoadFromFile('img1.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); Bmp.LoadFromFile('img2.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); Bmp.LoadFromFile('img3.bmp'); Bmp.Transparent := True; Gif.Add(Bmp); // add netscape loop if we want animation to keep repeating TGIFAppExtNSLoop.Create(Gif.Images.Frames[0]).Loops := 0; Gif.Pack; Gif.SaveToFile('test.gif'); finally Bmp.Free; Gif.Free; end; end; end.

Make sure the saved bitmaps are in the same folder as the project's exe (or change the filename paths) then run the project to create the output gif.

The saved output is not correct. From the penguin bitmaps saved above, I get this saved Gif:

You can see the frames are overlapping each other or something funky is going on! The source to this gif file can be found from here: http://www.animated-gifs.org.uk/agif/ani02.gif

I did not use all the frames from the Gif as there is so many, but you can see how it should work when animated.

Note that this does not happen with every gif, only a select few seem to save like this. Another example would be to try these bitmaps instead of the penguin:

The result is:

which should be (notice the flames on the plane):

To put it simply, I need to save a Gif from a series of bitmaps to be just like how they were when they were opened. You can see from the sample bitmaps above there is no inconsistency with the actual image data, so this makes me believe it is something to do with how they are added to the gif.

If I do need TGIfRenderer again I am not sure how to implement it for saving, I keep thinking it is for loading only?

This is one of those issues I get that I cannot solve. I've been trying to change the transparency and color and mode etc but I cannot seem to figure it out.

最满意答案

我不是GIFImg或gif图像的专家,但问题似乎与帧的处理有关。 在“GIFImg.pas”中搜索“处置”,我想出了下面的内容,它似乎适用于您的测试图像:

.... Gif.Add(Bmp); // last frame for i := 0 to Gif.Images.Count - 1 do for j := 0 to Gif.Images[i].Extensions.Count - 1 do if Gif.Images[i].Extensions[j] is TGIFGraphicControlExtension then TGIFGraphicControlExtension(Gif.Images[i].Extensions[j]).Disposal := dmBackground; ...

I'm not an expert with GIFImg or gif images but the problem seems to be related with disposal of frames. Searching for 'disposal' in 'GIFImg.pas', I came up with the below which seems to work for your test image:

.... Gif.Add(Bmp); // last frame for i := 0 to Gif.Images.Count - 1 do for j := 0 to Gif.Images[i].Extensions.Count - 1 do if Gif.Images[i].Extensions[j] is TGIFGraphicControlExtension then TGIFGraphicControlExtension(Gif.Images[i].Extensions[j]).Disposal := dmBackground; ...

更多推荐