当前帧: GIF.Images
能知道GIF文件播放完毕:GIF.Images.Count
procedure TForm1.Button1Click(Sender: TObject);
var
GIF : TGIFImage;
pFile : PAVIFile;
pStream : PAVISTREAM;
StreamInfo : TAVIStreamInfo;
BitmapInfo : PBitmapInfoHeader;
BitmapInfoSize : Integer;
BitmapSize : longInt;
BitmapBits : pointer;
Dummy : LONG;
i : integer;
HasLocalPalette : boolean;
begin
DoAbort := False;
ButtonAbort.Enabled := True;
ButtonAbort.Show;
ButtonAbort.SetFocus;
ButtonOpen.Enabled := False;
Screen.Cursor := crAppStart;
try
GIF := ImageGIF.Picture.Graphic as TGIFImage;
// Initialize the AVI file library
AVIFileInit;
try
// Open AVI file for write
if (AVIFileOpen(pFile, PChar(FileName), OF_WRITE or OF_CREATE OR OF_SHARE_EXCLUSIVE, nil) <> AVIERR_OK) then
raise Exception.Create('Failed to create AVI file');
try
// Determine size of DIB
InternalGetDIBSizes(GIF.Images[0].Bitmap.Handle, BitmapInfoSize, BitmapSize, pf8bit);
if (BitmapInfoSize = 0) then
raise Exception.Create('Failed to retrieve bitmap info');
// Set stream info
FillChar(StreamInfo, sizeof(StreamInfo), 0);
// Convert GIF frame delay to AVI frame rate and..
// ...determine if we need to equalize the palette
StreamInfo.dwRate := 65; // Should be 100, but that's too fast... }
StreamInfo.dwScale := 0;
HasLocalPalette := False;
for i := 0 to GIF.Images.Count-1 do
begin
if (GIF.Images.ColorMap.Count > 0) then
HasLocalPalette := True;
if (GIF.Images.GraphicControlExtension <> nil) then
StreamInfo.dwScale := GIF.Images.GraphicControlExtension.Delay;
// Break if both palette and delay has been determined
if (HasLocalPalette) and (StreamInfo.dwScale > 0) then
break;
end;
if (StreamInfo.dwScale = 0) then
StreamInfo.dwScale := 1;
StreamInfo.fccType := streamtypeVIDEO;
StreamInfo.fccHandler := 0;
StreamInfo.dwFlags := 0;
StreamInfo.dwSuggestedBufferSize := BitmapSize;
StreamInfo.rcFrame.Right := GIF.Width;
StreamInfo.rcFrame.Bottom := GIF.Height;
if (HasLocalPalette) then
// Force GIFs to be dithered to a single common palette
GIF.DrawOptions := GIF.DrawOptions + [goDither] - [goAutoDither];
// Open AVI data stream
if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then
raise Exception.Create('Failed to create AVI stream');
try
BitmapInfo := nil;
BitmapBits := nil;
try
// Get DIB header and pixel buffers
GetMem(BitmapInfo, BitmapInfoSize);
GetMem(BitmapBits, BitmapSize);
InternalGetDIB(GIF.Images[0].Bitmap.Handle, 0, BitmapInfo^, BitmapBits^, pf8bit);
// Set AVI format from DIB info
if (AVIStreamSetFormat(pStream, 0, BitmapInfo, BitmapInfoSize) <> AVIERR_OK) then
raise Exception.Create('Failed to set AVI stream format');
ProgressBar.Min := 0;
ProgressBar.Max := GIF.Images.Count-1;
ProgressBar.Position := 0;
ProgressBar.Show;
try
for i := 0 to GIF.Images.Count-1 do
begin
ProgressBar.Position := i;
Application.ProcessMessages;
if (DoAbort) then
exit;
if (GIF.Images.Empty) then
Continue;
if (i > 0) then
InternalGetDIB(GIF.Images.Bitmap.Handle, 0, BitmapInfo^, BitmapBits^, pf8bit);
// Write GIF frame to AVI
if AVIStreamWrite(pStream, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME, Dummy, Dummy) <>AVIERR_OK then
raise Exception.Create('Failed to add frame to AVI');
end;
finally
ProgressBar.Hide;
end;
finally
if (BitmapInfo <> nil) then
FreeMem(BitmapInfo);
if (BitmapBits <> nil) then
FreeMem(BitmapBits);
end;
finally
AVIStreamRelease(pStream);
end;
finally
AVIFileRelease(pFile);
end;
finally
AVIFileExit;
end;
{$ifndef VER90}
// Load and view AVI
try
AnimateAVI.FileName := Filename;
AnimateAVI.Active := True;
AnimateAVI.Show;
except
AnimateAVI.Hide;
AnimateAVI.Active := False;
PanelAVI.Caption := 'Cannot preview AVI';
end;
{$endif}
finally
Screen.Cursor := crDefault;
ButtonAbort.Hide;
ButtonOpen.Enabled := True;
end;
end;