1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547:
| //________Programm________ program AVIBuilder;
uses Forms, AniTool in 'AniTool.pas' {AniToolForm}, VFW in 'vfw.pas', DIBitmap in 'DIBitmap.pas', IUnk in 'IUnk.pas';
{$R *.RES}
begin Application.Initialize; Application.CreateForm(TAniToolForm, AniToolForm); Application.Run; end.
//________MainForm_________ unit AniTool;
{This tool allows the user to easily create avi files for use, for example, with the Delphi/C++Builder TAnimate component. It is an improvement on an old freeware thing I found lying around somewhere. Unfortunately I don't know who wrote the original, but all of the work in VFW and DIBitmap is his (or hers).
You can use this software however you want so long as it remains free. Please leave in some mention of Anderson Software. Also, if anyone knows who did the work on VFW and DIBitmap, please add their names too.
I think its use is pretty obvious. Add some bitmaps, sort them and then create the avi. It has to be saved before the preview starts. The frame counter lets you speed up or slow down the animation, but it has to be saved again before the change registers (as do any changes of frame order).
17 December 1998 Rob Anderson Anderson Software - Geneva, Switzerland anderson@nosredna.com }
interface
uses SysUtils, ComCtrls, StdCtrls, Spin, Buttons, ToolWin, Menus, Dialogs, ExtCtrls, Controls, Classes, Forms;
type TAniToolForm = class(TForm) BitmapListBox: TListBox; AddBitmapDialog: TOpenDialog; SaveAVIDialog: TSaveDialog; Panel2: TPanel; Panel3: TPanel; Splitter1: TSplitter; Animate1: TAnimate; Label1: TLabel; ToolBar1: TToolBar; SpeedButton4: TSpeedButton; SpeedButton3: TSpeedButton; SpeedButton2: TSpeedButton; SpeedButton5: TSpeedButton; SpeedButton6: TSpeedButton; spinRate: TSpinEdit; SpeedButton1: TSpeedButton; ToolButton1: TToolButton; ToolButton2: TToolButton; ToolButton3: TToolButton; ToolButton4: TToolButton; ToolButton5: TToolButton; Panel1: TPanel; BitmapImage: TImage; Label2: TLabel; StatusBar1: TStatusBar; procedure SpeedButton4Click(Sender: TObject); procedure BitmapListBoxClick(Sender: TObject); procedure SpeedButton3Click(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure SpeedButton2Click(Sender: TObject); procedure SpeedButton5Click(Sender: TObject); procedure SpeedButton6Click(Sender: TObject); private { Private Declarations } public { Public Declarations } end;
var AniToolForm: TAniToolForm;
implementation
uses Windows, Graphics, VFW, DIBitmap;
{$R *.DFM}
procedure TAniToolForm.SpeedButton4Click(Sender: TObject); var MyBitmap: TBitmap; i: Integer; begin with AddBitmapDialog do if Execute then for i:=0 to Files.Count-1 do begin MyBitmap := TBitmap.Create; MyBitmap.LoadFromFile(Files[i]); BitmapListBox.Items.AddObject(ExtractFileName(Files[i]),MyBitmap); end; end;
procedure TAniToolForm.BitmapListBoxClick(Sender: TObject); begin with BitmapListBox do if SelCount>1 then BitmapImage.Picture := nil else BitmapImage.Picture.Bitmap := Items.Objects[ItemIndex] as TBitmap; end;
procedure TAniToolForm.SpeedButton3Click(Sender: TObject); var i: Integer; begin with BitmapListBox do for i:=Items.Count-1 downto 0 do if Selected[i] then begin (Items.Objects[i] as TBitmap).Free; Items.Delete(i); end; end;
procedure TAniToolForm.SpeedButton1Click(Sender: TObject); var i: Integer; pfile: PAVIFile; asi: TAVIStreamInfo; ps: PAVIStream; nul: Longint;
BitmapInfo: PBitmapInfoHeader; BitmapInfoSize: Integer; BitmapBits: Pointer; BitmapSize: Integer; begin Animate1.Filename := ''; Animate1.Active := False;
with BitmapListBox, SaveAVIDialog do if Execute then begin AVIFileInit;
if AVIFileOpen(pfile, PChar(FileName), OF_WRITE or OF_CREATE, nil)=AVIERR_OK then begin FillChar(asi,sizeof(asi),0);
asi.fccType := streamtypeVIDEO; // Now prepare the stream asi.fccHandler := 0; asi.dwScale := 1; asi.dwRate := spinRate.Value;
with Items.Objects[0] as TBitmap do begin InternalGetDIBSizes(Handle,BitmapInfoSize,DWORD(BitmapSize),Integer(256)); BitmapInfo := AllocMem(BitmapInfoSize); BitmapBits := AllocMem(BitmapSize); InternalGetDIB(Handle,0,BitmapInfo^,BitmapBits^,256); end;
asi.dwSuggestedBufferSize := BitmapInfo^.biSizeImage; asi.rcFrame.Right := BitmapInfo^.biWidth; asi.rcFrame.Bottom := BitmapInfo^.biHeight;
if AVIFileCreateStream(pfile,ps,asi)=AVIERR_OK then with (Items.Objects[0] as TBitmap) do begin InternalGetDIB(Handle,0,BitmapInfo^,BitmapBits^,256); if AVIStreamSetFormat(ps,0,BitmapInfo,BitmapInfoSize)=AVIERR_OK then begin for i:=0 to Items.Count-1 do with (Items.Objects[i] as TBitmap) do begin InternalGetDIB(Handle,0,BitmapInfo^,BitmapBits^,256); if AVIStreamWrite(ps,i,1,BitmapBits,BitmapSize,AVIIF_KEYFRAME,nul,nul)<>AVIERR_OK then begin raise Exception.Create('Could not add frame'); break; end; end; end; end; FreeMem(BitmapInfo); FreeMem(BitmapBits); end;
AVIStreamRelease(ps); AVIFileRelease(pfile);
AVIFileExit; end; if FileExists(SaveAVIDialog.Filename) then begin Animate1.Filename := SaveAVIDialog.Filename; Animate1.Active := True; end; end;
procedure TAniToolForm.SpeedButton2Click(Sender: TObject); var jnSelectedItem : word; begin jnSelectedItem := BitmapListBox.ItemIndex; if jnSelectedItem > 0 then begin BitmapListBox.Items.Move(jnSelectedItem, jnSelectedItem - 1); BitmapListBox.Selected[jnSelectedItem - 1] := True; end; end;
procedure TAniToolForm.SpeedButton5Click(Sender: TObject); var jnSelectedItem : word; begin jnSelectedItem := BitmapListBox.ItemIndex; if jnSelectedItem < BitmapListBox.Items.Count - 1 then begin BitmapListBox.Items.Move(jnSelectedItem, jnSelectedItem + 1); BitmapListBox.Selected[jnSelectedItem + 1] := True; end; end;
procedure TAniToolForm.SpeedButton6Click(Sender: TObject); begin BitmapListBox.Sorted := not BitmapListBox.Sorted; end;
end.
//__________VFW___________ unit VFW;
{ don't know who wrote this - the AVI section for avifil32.dll - Thanks !!!}
interface
uses Windows, IUnk;
type
{ TAVIFileInfoW record }
LONG = Longint; PVOID = Pointer;
TAVIFileInfoW = record dwMaxBytesPerSec, // max. transfer rate dwFlags, // the ever-present flags dwCaps, dwStreams, dwSuggestedBufferSize,
dwWidth, dwHeight,
dwScale, dwRate, // dwRate / dwScale == samples/second dwLength,
dwEditCount: DWORD;
szFileType: array[0..63] of WideChar; // descriptive string for file type? end; PAVIFileInfoW = ^TAVIFileInfoW;
{ TAVIStreamInfoA record }
TAVIStreamInfoA = record fccType, fccHandler, dwFlags, // Contains AVITF_* flags dwCaps: DWORD; wPriority, wLanguage: WORD; dwScale, dwRate, // dwRate / dwScale == samples/second dwStart, dwLength, // In units above... dwInitialFrames, dwSuggestedBufferSize, dwQuality, dwSampleSize: DWORD; rcFrame: TRect; dwEditCount, dwFormatChangeCount, szName: array[0..63] of AnsiChar; end; TAVIStreamInfo = TAVIStreamInfoA; { TAVIStreamInfoW record }
TAVIStreamInfoW = record fccType, fccHandler, dwFlags, // Contains AVITF_* flags dwCaps: DWORD; wPriority, wLanguage: WORD; dwScale, dwRate, // dwRate / dwScale == samples/second dwStart, dwLength, // In units above... dwInitialFrames, dwSuggestedBufferSize, dwQuality, dwSampleSize: DWORD; rcFrame: TRect; dwEditCount, dwFormatChangeCount, szName: array[0..63] of WideChar; end;
{ IAVIStream interface }
IAVIStream = class(IUnknown) function Create(lParam1, lParam2: LPARAM): HResult; virtual; stdcall; abstract; function Info(var psi: TAVIStreamInfoW; lSize: LONG): HResult; virtual; stdcall; abstract; function FindSample(lPos, lFlags: LONG): LONG; virtual; stdcall; abstract; function ReadFormat(lPos: LONG; lpFormat: PVOID; var lpcbFormat: LONG): HResult; virtual; stdcall; abstract; function SetFormat(lPos: LONG; lpFormat: PVOID; lpcbFormat: LONG): HResult; virtual; stdcall; abstract; function Read(lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; var plBytes: LONG; var plSamples: LONG): HResult; virtual; stdcall; abstract; function Write(lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; virtual; stdcall; abstract; function Delete(lStart, lSamples: LONG): HResult; virtual; stdcall; abstract; function ReadData(fcc: DWORD; lp: PVOID; var lpcb: LONG): HResult; virtual; stdcall; abstract; function WriteData(fcc: DWORD; lp: PVOID; cb: LONG): HResult; virtual; stdcall; abstract; function SetInfo(var lpInfo: TAVIStreamInfoW; cbInfo: LONG): HResult; virtual; stdcall; abstract; end; PAVIStream = ^IAVIStream;
{ IAVIFile interface }
IAVIFile = class(IUnknown) function Info(var pfi: TAVIFileInfoW; lSize: LONG): HResult; virtual; stdcall; abstract; function GetStream(var ppStream: PAVIStream; fccType: DWORD; lParam: LONG): HResult; virtual; stdcall; abstract; function CreateStream(var ppStream: PAVIStream; var pfi: TAVIFileInfoW): HResult; virtual; stdcall; abstract; function WriteData(ckid: DWORD; lpData: PVOID; cbData: LONG): HResult; virtual; stdcall; abstract; function ReadData(ckid: DWORD; lpData: PVOID; var lpcbData: LONG): HResult; virtual; stdcall; abstract; function EndRecord: HResult; virtual; stdcall; abstract; function DeleteStream(fccType: DWORD; lParam: LONG): HResult; virtual; stdcall; abstract; end; PAVIFile = ^IAVIFile;
procedure AVIFileInit; stdcall; procedure AVIFileExit; stdcall; function AVIFileOpen(var ppfile: PAVIFile; szFile: LPCSTR; uMode: UINT; lpHandler: PCLSID): HResult; stdcall; function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVISTREAM; var psi: TAVIStreamInfoA): HResult; stdcall; function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: PVOID; cbFormat: LONG): HResult; stdcall; function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; stdcall; function AVIStreamRelease(pavi: PAVISTREAM): ULONG; stdcall; function AVIFileRelease(pfile: PAVIFile): ULONG; stdcall;
const AVIERR_OK = 0;
AVIIF_LIST = $01; AVIIF_TWOCC = $02; AVIIF_KEYFRAME = $10;
streamtypeVIDEO = $73646976; // DWORD( 'v', 'i', 'd', 's' )
{ AVI interface IDs }
IID_IAVIFile: TGUID = ( D1:$00020020;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46)); IID_IAVIStream: TGUID = ( D1:$00020021;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46)); IID_IAVIStreaming: TGUID = ( D1:$00020022;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46)); IID_IGetFrame: TGUID = ( D1:$00020023;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46)); IID_IAVIEditStream: TGUID = ( D1:$00020024;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
{ AVI class IDs }
CLSID_AVISimpleUnMarshal: TGUID = ( D1:$00020009;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46)); CLSID_AVIFile: TGUID = ( D1:$00020000;D2:$0;D3:$0;D4:($C0,$0,$0,$0,$0,$0,$0,$46));
implementation
procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit'; procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit'; function AVIFileOpen(var ppfile: PAVIFILE; szFile: LPCSTR; uMode: UINT; lpHandler: PCLSID): HResult; external 'avifil32.dll' name 'AVIFileOpenA'; function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVIStream; var psi: TAVIStreamInfoA): HResult; external 'avifil32.dll' name 'AVIFileCreateStreamA'; function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: PVOID; cbFormat: LONG): HResult; external 'avifil32.dll' name 'AVIStreamSetFormat'; function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: PVOID; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; external 'avifil32.dll' name 'AVIStreamWrite'; function AVIStreamRelease(pavi: PAVIStream): ULONG; external 'avifil32.dll' name 'AVIStreamRelease'; function AVIFileRelease(pfile: PAVIFile): ULONG; external 'avifil32.dll' name 'AVIFileRelease';
end.
//_________IUnk_____________ unit IUnk;
{This allows us to subclass IUnknown without having to include the now defunct ole2.pas.
17 December 1998 Rob Anderson Anderson Software - Geneva, Switzerland anderson@nosredna.com }
interface
uses Windows;
type
{ Result code }
HResult = Longint;
{ Globally unique ID }
PGUID = ^TGUID; TGUID = record D1: Longint; D2: Word; D3: Word; D4: array[0..7] of Byte; end;
{ Interface ID }
PIID = PGUID; TIID = TGUID;
{ Class ID }
PCLSID = PGUID; TCLSID = TGUID;
{ IUnknown interface }
IUnknown = class public function QueryInterface(const iid: TIID; var obj): HResult; virtual; stdcall; abstract; function AddRef: Longint; virtual; stdcall; abstract; function Release: Longint; virtual; stdcall; abstract; end;
implementation
end.
//_________DIBitMap__________ unit DIBitmap;
{ don't know who wrote this - Thanks !!!}
interface
uses Windows, SysUtils, Classes;
procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var BI: TBitmapInfoHeader; Colors: Integer);
procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; var ImageSize: DWORD; Colors: Integer);
function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; var BitmapInfo; var Bits; Colors: Integer): Boolean;
implementation
procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var BI: TBitmapInfoHeader; Colors: Integer); var BM: Windows.TBitmap; begin GetObject(Bitmap, SizeOf(BM), @BM); with BI do begin biSize := SizeOf(BI); biWidth := BM.bmWidth; biHeight := BM.bmHeight; if Colors <> 0 then case Colors of 2: biBitCount := 1; 16: biBitCount := 4; 256: biBitCount := 8; end else biBitCount := BM.bmBitsPixel * BM.bmPlanes; biPlanes := 1; biXPelsPerMeter := 0; biYPelsPerMeter := 0; if biBitCount>8 then biClrUsed := 0 else biClrUsed := Colors; biClrImportant := 0; biCompression := BI_RGB; if biBitCount in [16, 32] then biBitCount := 24; biSizeImage := (((biWidth * biBitCount) + 31) div 32) * 4 * biHeight; end; end;
procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; var ImageSize: DWORD; Colors: Integer); var BI: TBitmapInfoHeader; begin InitializeBitmapInfoHeader(Bitmap, BI, Colors); with BI do begin case biBitCount of 24: InfoHeaderSize := SizeOf(TBitmapInfoHeader); else InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl biBitCount); end; end; ImageSize := BI.biSizeImage; end;
function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; var BitmapInfo; var Bits; Colors: Integer): Boolean; var OldPal: HPALETTE; Focus: HWND; DC: HDC; begin InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), Colors); OldPal := 0; Focus := GetFocus; DC := GetDC(Focus); try if Palette <> 0 then begin OldPal := SelectPalette(DC, Palette, False); RealizePalette(DC); end; Result := GetDIBits(DC, Bitmap, 0, TBitmapInfoHeader(BitmapInfo).biHeight, @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0; finally if OldPal <> 0 then SelectPalette(DC, OldPal, False); ReleaseDC(Focus, DC); end; end;
end. |