如何在Delphi 7中将双列伺服动画GIF拆分为两个独立序列?
Delphi 7拆分GIF帧为左右两半的代码修改
我正在开发与ATMEL 2560通信的Delphi程序,该设备接收指令控制伺服电机运动并将位置反馈到程序的Edit框,这部分功能运行正常。现在需要实现图形化展示,找到一张包含两列伺服动画的GIF:左列位置伺服在42帧内完成-90°到+90°再返回-90°的运动;右列旋转伺服在42帧内完成整圈旋转,两者同步。
我是Delphi动画开发新手,已经在Delphi 7 Enterprise(XP SP4)中安装了GIFIMAGE单元,能打开GIF、提取单帧并保存为BMP,但不知道如何将每帧拆分为左右两半,请帮忙修改代码。
原代码:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, GifImage, XPman, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private Gif : TGifImage; { Private declarations } public { Public declarations } end; var Form1 : TForm1; BMP : TBitmap; Curdir : String; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); VAR I : Integer; begin Curdir := 'g:\servo\'; GIF := TGifImage.Create(); Gif.LoadFromFile(Curdir + 'servos-1.gif'); Bmp := TBitmap.Create; Bmp.PixelFormat := pf24bit; end; procedure TForm1.FormDestroy(Sender: TObject); begin BMP.Free; GIF.Free; end; procedure TForm1.Button1Click(Sender: TObject); VAR i : Integer; begin // Bmp.Width := Gif.Width div 2; Bmp.Height := Gif.Height; For i := 0 to Gif.Images.Count-1 do begin Bmp.Width := Gif.Width div 2; Bmp.Assign(Gif.Images.SubImages[i].Bitmap); Bmp.SaveToFile(Curdir + 'Serv' + IntToStr(i) + '.bmp'); END; end; END.
修改后的代码:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, GifImage, XPman, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private Gif : TGifImage; { Private declarations } public { Public declarations } end; var Form1 : TForm1; BMPLeft, BMPRight : TBitmap; // 分别存储左右两半的帧位图 Curdir : String; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin Curdir := 'g:\servo\'; GIF := TGifImage.Create(); Gif.LoadFromFile(Curdir + 'servos-1.gif'); // 初始化左半帧位图 BMPLeft := TBitmap.Create; BMPLeft.PixelFormat := pf24bit; BMPLeft.Width := Gif.Width div 2; BMPLeft.Height := Gif.Height; // 初始化右半帧位图 BMPRight := TBitmap.Create; BMPRight.PixelFormat := pf24bit; BMPRight.Width := Gif.Width div 2; BMPRight.Height := Gif.Height; end; procedure TForm1.FormDestroy(Sender: TObject); begin BMPLeft.Free; BMPRight.Free; GIF.Free; end; procedure TForm1.Button1Click(Sender: TObject); VAR i : Integer; FrameBmp: TBitmap; begin FrameBmp := TBitmap.Create; try FrameBmp.PixelFormat := pf24bit; For i := 0 to Gif.Images.Count-1 do begin // 加载当前GIF帧到临时位图 FrameBmp.Assign(Gif.Images.SubImages[i].Bitmap); // 复制左半区域到BMPLeft BitBlt(BMPLeft.Canvas.Handle, 0, 0, BMPLeft.Width, BMPLeft.Height, FrameBmp.Canvas.Handle, 0, 0, SRCCOPY); BMPLeft.SaveToFile(Curdir + 'ServoLeft_' + IntToStr(i) + '.bmp'); // 复制右半区域到BMPRight BitBlt(BMPRight.Canvas.Handle, 0, 0, BMPRight.Width, BMPRight.Height, FrameBmp.Canvas.Handle, BMPLeft.Width, 0, SRCCOPY); BMPRight.SaveToFile(Curdir + 'ServoRight_' + IntToStr(i) + '.bmp'); END; finally FrameBmp.Free; // 确保临时位图资源释放 end; end; END.
关键修改说明
- 新增
BMPLeft和BMPRight两个位图对象,分别存储每帧的左右两半 - 使用
BitBltAPI精确复制位图区域:- 左半帧:从原帧的(0,0)位置复制到BMPLeft
- 右半帧:从原帧的(原宽度/2, 0)位置复制到BMPRight
- 添加临时位图
FrameBmp避免重复赋值时的资源冲突,通过try-finally确保资源安全释放
内容的提问来源于stack exchange,提问作者Kristian Sander
相关产品推荐
相关产品推荐

