【发布时间】:2016-04-06 07:15:47
【问题描述】:
我有这个从动画 GIF 中提取帧的函数。它适用于除此之外的所有 GIF:
{ Loads a GIF. Returns a list of BMP frames }
function GetGifFrames(GifFile: string): TObjectList;
var
GIF: TGIFImage;
TempFrame: TBitmap;
Frame: TBitmap;
Counter: Integer;
GR: TGIFRenderer;
begin
{ Load GIF }
GIF := TGIFImage.Create;
TRY
TRY
Gif.Animate := FALSE;
GIF.LoadFromFile(GifFile);
EXCEPT
MesajError('Cannot load '+ GifFile);
EXIT(NIL);
END;
if Gif.Images.Count= 1 then
begin
MsgError('This is not an animated GIF'+ CRLF+ GifFile);
EXIT(NIL);
end;
Result:= TObjectList.Create;
Result.OwnsObjects:= TRUE; { Array of images }
{ GIF render }
TempFrame:= TBitmap.Create;
GR:= TGIFRenderer.Create(GIF); { GIF render }
TRY
TempFrame.SetSize(GIF.Width, GIF.Height);
for Counter:= 0 to GIF.Images.Count-1 DO
begin
{ Skip bad frames }
if GIF.Images[Counter].Empty
then Continue;
{ Create new frame }
Frame:= TBitmap.Create;
Frame.SetSize(GIF.Width, GIF.Height);
GR.Draw(TempFrame.Canvas, TempFrame.Canvas.ClipRect); <---------- AV here { Transfer image from GIF to BMP }
Frame.Assign(TempFrame);
Result.Add(Frame); { Add to list of bitmap frames }
GR.NextFrame; { Advance }
end;
FINALLY
FreeAndNil(GR);
FreeAndNil(TempFrame);
END;
FINALLY
FreeAndNil(GIF);
END;
end;
我在上面指示的行上有一个 AV
调试器异常通知项目 Tester.exe 引发异常 类 $C0000005 与消息“访问冲突在 0x005d3924:读取 地址 0x0000002c'。
堆栈跟踪是:
GetGifFrames('C:\Test gif\err.gif')
GIFImg.TGIFRenderer.Draw($7EFA9070,(0, 0, 108, 146, (0, 0), (108, 146)))
GIFImg.TGIFRenderer.GetBitmap
GIFImg.TGIFRenderer.RenderFrame
在渲染框架中,它在这一行崩溃:
PreviousBuffer.Canvas.CopyRect(PreviousBuffer.Canvas.ClipRect, Buffer.Canvas, Buffer.Canvas.ClipRect);
这是因为 PreviousBuffer 为 NIL!!!!
如何解决这个问题?
【问题讨论】:
-
当您在
GR.Draw(TempFrame.Canvas, TempFrame.Canvas.ClipRect);行设置断点时,TempFrame中的GR中存储了什么值? -
@ZamronyP.Juhara - TempFrame.Width 和 Height 的值没问题(gif 大小为 108x146)。 ClipRect 也可以。也许这个特定的 GIF 格式不正确?
-
为什么显示完整的错误信息这么难,你不觉得可能有一些有价值的信息吗?顺便说一句,我用图像(“Sansanimated.gif”)测试了你的代码,但没有 AV,也没有任何其他错误,
TObjectList中有 13 帧。 -
读取地址 0x0000002C 看起来像访问 nil 对象引用,并且由于您只访问
TempFrame及其Canvas,要么是 nil 吗?当然在你的代码中他们不应该,但是...... -
@TomBrunberg-嗨,汤姆。 1. 测试仪(DPR、PAS、DFM 文件)在这里可用:s000.tinyupload.com/… 还有编译文件(exe)将显示 AV(以防您仍然无法在您的计算机中重现)。 2. 我认为当您尝试访问 nil obj 时,您会得到“读取地址 00000000”。
标签: delphi graphics gif delphi-xe7