如何转换位图视频? [英] How to convert bitmaps to video?

查看:383
本文介绍了如何转换位图视频?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序创建从分形图像和我爱的飞行围绕一个分形的感觉。我曾经救过约2000位图文件,并使用premiere创建的AVI如此。经验是相当令人沮丧,但我成功地创建了电影。这是壮观。当然,我想从我的应用程序创建一个视频。我其实并不关心codeC的niftynes​​s,COM pression或什么的。我只是想有,我可以在大多数系统上重放视频。

在过去,我试过,但没有成功。我被一个<一个触发href=\"http://stackoverflow.com/questions/9584025/creating-a-motion-jpeg-frame-by-frame-with-variable-frame-rate\">question最近,但可惜无法得到FFmpeg的运行。

更新

我决定稍微适应的问题,并把赏金吧。我见过几个解决方案,但最有吸引力的(因为它的简单)在我看来TAviWrite。我试着TAviWriter,但没有成功。在程序TAviWriter.Write;围绕线函数调用370

  AVIERR:= AVISaveV(S,
// PChar类型(文件名),
               零,//文件处理程序
               零,//回调
               nStreams,//流数
               流,
               CompOptions);对于视频流//的COM preSS选项

不返回AVIERR_OK。

更新2

原因上述的错误是AVISaveV的一个错误的声明,应该被声明为AVISaveVW作为TLama指出。正确的code创建AVI filoes形式的BMP文件如下公布。低于原来的code是从一个例子单元EFG 下载

在Windows 7使用德尔福XE。

 单元AviWriter;////////////////////////////////////////////////// ///////////////////////////
// //
// AviWriter - 创建基本的AVI文件的组件//
//由埃利奥特Shevin,用大块code的//
//从安德斯·梅兰德被盗//
// 1.0版。请把意见,建议和建议//
//为shevine@aol.com。 //
////////////////////////////////////////////////// ///////////////////////////接口用途
  Windows的消息,SysUtils单元,类图形,控件,表格,对话框,
  StdCtrls中,OLE2;////////////////////////////////////////////////// //////////////////////////////
// //
// Windows视频//
// //
////////////////////////////////////////////////// //////////////////////////////
// //
//托马斯Schimming的VFW.PAS //改编
//(三)1996年托马斯Schimming,schimmin@iee1.et.tu-dresden.de //
//(三)1998,99安德斯·梅兰德//
// //
////////////////////////////////////////////////// //////////////////////////////
// //
//剥去所有的COM / ActiveX的东西,并增加了一些AVI流功能。 //
// //
////////////////////////////////////////////////// //////////////////////////////
由阿诺德和TLama(2012)//创建统一code版本//
////////////////////////////////////////////////// //////////////////////////////类型
  龙= Longint型;
  PVOID =指针;常量
// TAVIFileInfo dwFlag值
   AVIF_HASINDEX = $ 00000010;
   AVIF_MUSTUSEINDEX = $ 00000020;
   AVIF_ISINTERLEAVED = $ 00000100;
   AVIF_WASCAPTUREFILE = $ 00010000;
   AVIF_COPYRIGHTED = $ 00020000;
   AVIF_KNOWN_FLAGS = $零零零三零一三零;   AVIERR_UNSUPPORTED = $八零零四四零六五; // MAKE_AVIERR(101)
   AVIERR_BADFORMAT = $八○○四四○六六; // MAKE_AVIERR(102)
   AVIERR_MEMORY = $八千零四万四千零六十七; // MAKE_AVIERR(103)
   AVIERR_INTERNAL = $八千零四万四千零六十八; // MAKE_AVIERR(104)
   AVIERR_BADFLAGS = $八○○四四○六九; // MAKE_AVIERR(105)
   AVIERR_BADPARAM = $ 8004406A; // MAKE_AVIERR(106)
   AVIERR_BADSIZE = $ 8004406B; // MAKE_AVIERR(107)
   AVIERR_BADHANDLE = $ 8004406C; // MAKE_AVIERR(108)
   AVIERR_FILEREAD = $ 8004406D; // MAKE_AVIERR(109)
   AVIERR_FILEWRITE = $ 8004406E; // MAKE_AVIERR(110)
   AVIERR_FILEOPEN = $ 8004406F; // MAKE_AVIERR(111)
   AVIERR_COM preSSOR = 80044070 $; // MAKE_AVIERR(112)
   AVIERR_NOCOM preSSOR = 80044071 $; // MAKE_AVIERR(113)
   AVIERR_READONLY = $ 80044072; // MAKE_AVIERR(114)
   AVIERR_NODATA = $八○○四四○七三; // MAKE_AVIERR(115)
   AVIERR_BUFFERTOOSMALL = $ 80044074; // MAKE_AVIERR(116)
   AVIERR_CANTCOM $ P $ =干燥综合征$ 80044075; // MAKE_AVIERR(117)
   AVIERR_USERABORT = $ 800440C6; // MAKE_AVIERR(198)
   AVIERR_ERROR = $ 800440C7; // MAKE_AVIERR(199)// TAVIStreamInfo dwFlag值
   AVISF_DISABLED = $ 00000001;
   AVISF_VIDEO_PALCHANGES = $ 00010000;
   AVISF_KNOWN_FLAGS = $ 00010001;类型
  TAVIFileInfoW =记录
    dwMaxBytesPerSec,//最大。传输速率
    dwFlags中,//在ever- present标志
    dwCaps,
    dwStreams,
    dwSuggestedBufferSize,    dwWidth,
    dwHeight,    dwScale,
    dwRate,// dwRate / dwScale ==采样/秒
    dwLength,    dwEditCount:DWORD;    szFileType:数组WideChar的[0..63] //描述字符串的文件类型?
  结束;
  PAVIFileInfoW = ^ TAVIFileInfoW;  TAVIStreamInfoW =记录
    fccType,
    fccHandler,
    dwFlags中,//包含AVITF_ *标志
    dwCaps:DWORD;
    wPriority,
    wLanguage:WORD;
    dwScale,
    dwRate,// dwRate / dwScale ==采样/秒
    dwStart,
    dwLength,//在上面的单位...
    dwInitialFrames,
    dwSuggestedBufferSize,
    dwQuality,
    dwSampleSize:DWORD;
    rcFrame:TRect;
    dwEditCount,
    dwFormatChangeCount:DWORD;
    szName的:数组WideChar的[0..63]
  结束;
  TAVIStreamInfo = TAVIStreamInfoW;
  PAVIStreamInfo = ^ TAVIStreamInfo;  PAVIStream =指针;
  PAVIFile =指针;
  TAVIStreamList =阵列PAVIStream的[0..0]
  PAVIStreamList = ^ TAVIStreamList;
  TAVISaveCallback =功能(nPercent:整数):长; STDCALL;  TAVICom pressOptions =包装记录
    fccType:DWORD;
    fccHandler:DWORD;
    dwKeyFrameEvery:DWORD;
    dwQuality:DWORD;
    dwBytesPerSecond:DWORD;
    dwFlags中:DWORD;
    lpFormat:指针;
    cbFormat:DWORD;
    lpParms:指针;
    cbParms:DWORD;
    dwInterleaveEvery:DWORD;
  结束;
  PAVICom pressOptions = ^ TAVICom pressOptions;//调色板变化数据记录
常量
  RIFF_PaletteChange:DWORD = 1668293411;类型
  TAVIPalChange =包装记录
    bFirstEntry:字节;
    bNumEntries:字节;
    wFlags:WORD;
    peNew:数组TPaletteEntry的(字节);
  结束;
  PAVIPalChange = ^ TAVIPalChange;  APAVISTREAM =阵列PAVISTREAM的[0..1]
  APAVICom pressOptions =阵列PAVICom pressOptions的[0..1]
程序AVIFileInit; STDCALL;
程序AVIFileExit; STDCALL;
功能AVIFileOpen(VAR ppfile:PAVIFile; szFile:PChar类型; uMode:UINT; lpHandler:指针):HRESULT; STDCALL;
功能AVIFileCreateStream(PFILE:PAVIFile; VAR ppavi:PAVISTREAM; VAR PSI:TAVIStreamInfo):HRESULT; STDCALL;
功能AVIStreamSetFormat(PAVI:PAVIStream; LPOS:LONG; lpFormat:指针; cbFormat:LONG):HRESULT; STDCALL;
功能AVIStreamReadFormat(PAVI:PAVIStream; LPOS:LONG; lpFormat:指针; VAR cbFormat:LONG):HRESULT; STDCALL;
功能AVIStreamWrite(PAVI:PAVIStream; lStart,lSamples:LONG; lpBuffer:指针; cbBuffer:LONG; dwFlags中:DWORD; VAR plSampWritten:LONG; VAR plBytesWritten:LONG):HRESULT; STDCALL;
功能AVIStreamRelease(PAVI:PAVISTREAM):ULONG; STDCALL;
功能AVIFileRelease(PFILE:PAVIFile):ULONG; STDCALL;
功能AVIFileGetStream(PFILE:PAVIFile; VAR ppavi:PAVISTREAM; fccType:DWORD; lParam的:LONG):HRESULT; STDCALL;
功能CreateEditableStream(VAR ppsEditable:PAVISTREAM; psSource:PAVISTREAM):HRESULT; STDCALL;
功能AVISaveV(szFile:PChar类型; pclsidHandler:PCLSID; lpfnCallback:TAVISaveCallback;
  nStreams:整数; PAVI:APAVISTREAM; lpOptions:APAVICom pressOptions):HRESULT; STDCALL;常量
  AVIERR_OK = 0;  AVIIF_LIST = $ 01;
  AVIIF_TWOCC = $ 02;
  AVIIF_KEYFRAME = $ 10;  streamtypeVIDEO = $ 73646976; // DWORD('V','我','D','S')
  streamtypeAUDIO = $七千三百六十四万七千五百六十一; // DWORD('A','U','D','S')
类型
  TPixelFormat =(pfDevice,pf1bit,pf4bit,pf8bit,pf15bit,pf16bit,pf24bit,pf32bit,pfCustom);类型
  TAviWriter =类(TComponent)
  私人的
    TempFileName:字符串;
    PFILE:PAVIFile;
    fHeight:整数;
    fWidth:整数;
    fStretch:布尔;
    fFrameTime:整数;
    Ffilename要:字符串;
    fWavFileName:字符串;
    视频流:PAVISTREAM;
    语音串流:PAVISTREAM;    程序AddVideo;
    程序AddAudio;
    程序InternalGetDIBSizes(位图:HBITMAP; VAR InfoHeaderSize:整数;
        VAR IMAGESIZE:LONGINT;的PixelFormat:TPixelFormat);
    功能InternalGetDIB(位图:HBITMAP;调色板:HPALETTE;
        VAR BITMAPINFO; VAR位;的PixelFormat:TPixelFormat):布尔;
    程序InitializeBitmapInfoHeader(位图:HBITMAP; VAR信息:TBitmapInfoHeader;
           的PixelFormat:TPixelFormat);
    程序SetWavFileName(价值:字符串);  上市
    位图:从TList;
    构造函数创建(AOwner:TComponent);覆盖;
    析构函数销毁;覆盖;
    程序写;  发表
    属性Height:整数读fHeight写fHeight;
    属性width:整数读fWidth写fWidth;
    物业FRAMETIME:整数读fFrameTime写fFrameTime;
    物业拉伸:Boolean读出fStretch写fStretch;
    属性文件名:字符串读Ffilename要写Ffilename要;
    物业WavFileName:串读fWavFileName写SetWavFileName;
  结束;程序注册;履行程序AVIFileInit; STDCALL;外部avifil32.dll'名'AVIFileInit';
程序AVIFileExit; STDCALL;外部avifil32.dll'名'AVIFileExit';
功能AVIFileOpen;外部avifil32.dll'名'AVIFileOpenW';
功能AVIFileCreateStream;外部avifil32.dll'名'AVIFileCreateStreamW';
功能AVIStreamSetFormat;外部avifil32.dll'名'AVIStreamSetFormat';
功能AVIStreamReadFormat;外部avifil32.dll'名'AVIStreamReadFormat';
功能AVIStreamWrite;外部avifil32.dll'名'AVIStreamWrite';
功能AVIStreamRelease;外部avifil32.dll'名'AVIStreamRelease';
功能AVIFileRelease;外部avifil32.dll'名'AVIFileRelease';
功能AVIFileGetStream;外部avifil32.dll'名'AVIFileGetStream';
功能CreateEditableStream;外部avifil32.dll'名'CreateEditableStream';
功能AVISaveV;外部avifil32.dll'名'AVISaveVW';构造TAviWriter.Create(AOwner:TComponent);
开始
    继承创建(AOwner);
    fHeight:= screen.height DIV 10;
    fWidth:= screen.width DIV 10;
    fFrameTime:= 1000;
    fStretch:=真;
    Ffilename要:='';
    位图:= TList.create;
    AVIFileInit;
    TempFileName:= {TEMPDIR +}'temp.avi';
结束;析构函数TAviWriter.Destroy;
开始
    Bitmaps.free;
    AviFileExit;
    遗传;
结束;程序TAviWriter.Write;
VAR
  ExtBitmap:TBitmap;
  nstreams:整数;
  我:整数;
  流:APAVISTREAM;
  CompOptions:APAVICom pressOptions;
  AVIERR:整数;
  引用次数:整数;
开始
   语音串流:=零;
   视频流:=零;   //如果没有点阵图名单上,引发一个错误。
   如果Bitmaps.count&LT; 1
      然后抬起Exception.Create(下称位图列表上没有位图');   //如果对位图什么的TList是不是一个位图,提高
   // 一个错误。
   对于i:= 0 Bitmaps.count - 1做
   开始
      ExtBitmap:=位图[I]
      如果不是(ExtBitmap是TBitmap)
         然后抬起Exception.Create(位图['+ inttostr(I)
                       +]不是TBitmap');
   结束; //为   尝试
      AddVideo;      如果WavFileName&LT;&GT; ''
         然后AddAudio;      //创建输出文件。
      如果WavFileName&LT;&GT; ''
         然后nstreams:= 2
         别的nstreams:= 1;      流[0] =视频流;
      流[1]:=语音串流;
      CompOptions [0] =零;
      CompOptions [1]:=无;      AVIERR:= AVISaveV(
                   PChar类型(文件名),
                   零,//文件处理程序
                   零,//回调
                   nStreams,//流数
                   流,
                   CompOptions);对于视频流//的COM preSS选项
      如果AVIERR&LT;&GT; AVIERR_OK然后
             提高Exception.Create('无法写入输出文件');
   最后
      如果分配(视频流)
         然后AviStreamRelease(视频流);
      如果分配(语音串流)
         然后AviStreamRelease(语音串流);      尝试
         重复
            引用计数:= AviFileRelease(PFILE);
         直到引用计数&LT; = 0;
      除
         //忽略例外
      结束; // try..except      的DeleteFile(TempFileName);
   结束; // try..finally
结束;程序TAviWriter.AddVideo;
VAR
  Pstream:PAVISTREAM;
  StreamInfo:TAVIStreamInfo;
  BITMAPINFO:PBitmapInfoHeader;
  BitmapInfoSize:整数;
  BitmapSize:LONGINT;
  BitmapBits:指针;
  位图:TBitmap;
  ExtBitmap:TBitmap;
  Samples_Written:LONG;
  Bytes_Written:LONG;
  AVIERR:整数;
  我:整数;
  OK:Int64的;
  模式:为uInt32;
  FN:PCHAR;
  错误:字符串;
开始
    //为写打开AVI文件
    PFILE:=零;
    模式:= OF_CREATE或OF_WRITE或OF_SHARE_EXCLUSIVE;
    FN:= PChar类型(TempFileName);    OK:= AVIFileOpen(PFILE,FN,模式,无);
    如果正常= AVIERR_BADFORMAT再犯错:='文件无法读取,表示文件损坏或无法识别的格式。;
    如果正常= AVIERR_MEMORY再犯错:='的文件不能因为内存不足开。;
    如果正常= AVIERR_FILEREAD则错误:在读取文件时发生了磁盘错误。'=;
    如果正常= AVIERR_FILEOPEN则错误:打开文件时发生磁盘错误。'=;
    如果正常= REGDB_E_CLASSNOTREG再犯错:='根据注册表,文件中AVIFileOpen指定的类型没有一个处理程序处理它。;
    如果犯错&LT;&GT; ''再养Exception.Create(ERR);    //分配位图到对位图TLIST位图
    //将被复制。
    位图:= TBitmap.create;
    Bitmap.Height:= self.Height;
    Bitmap.Width:= self.Width;    //写入流头。
    尝试
       FillChar(StreamInfo,sizeof的(StreamInfo),0);       //设置帧速率和规模
       StreamInfo.dwRate:= 1000;
       StreamInfo.dwScale:= fFrameTime;
       StreamInfo.fccType:= streamtypeVIDEO;
       StreamInfo.fccHandler:= 0;
       StreamInfo.dwFlags:= 0;
       StreamInfo.dwSuggestedBufferSize:= 0;
       StreamInfo.rcFrame.Right:= self.width;
       StreamInfo.rcFrame.Bottom:= self.height;       //打开AVI数据流
       如果(AVIFileCreateStream(PFILE,pStream,StreamInfo)LT;&GT; AVIERR_OK),那么
           提高Exception.Create(无法创建AVI视频流');       尝试
          //写位图到流。
          对于i:= 0 Bitmaps.count - 1做
          开始
             BITMAPINFO:=零;
             BitmapBits:=零;
             尝试               //位图从列表复制到AVI位图,
               //如果需要伸展。如果主叫方选择不
               //拉伸,使用第一像素中的位图作为一个
               //如果背景颜色或者高度或
               //源的宽度比输出小。
               //如果绘制失败,做一个StretchDraw。
               ExtBitmap:=位图[I]
               如果fStretch
                  然后Bitmap.Canvas.StretchDraw
                           (矩形(0,0,self.width,self.height),ExtBitmap)
                  其他尝试
                         与Bitmap.Canvas开始做
                            Brush.Color:= ExtBitmap.Canvas.Pixels [0,0];
                            Brush.Style:= bsSolid;
                            FillRect(矩形(0,0,Bitmap.Width,Bitmap.Height));
                            绘制(0,0,ExtBitmap);
                         结束;
                       除
                         Bitmap.Canvas.StretchDraw
                            (矩形(0,0,self.width,self.height),ExtBitmap);
                       结束;               //确定DIB的大小
               InternalGetDIBSizes(Bitmap.Handle,BitmapInfoSize,BitmapSize,pf8bit);
               如果(BitmapInfoSize = 0),那么
                  提高Exception.Create(无法检索位图信息);               //获取DIB头和像素缓冲区
               GetMem例程(BITMAPINFO,BitmapInfoSize);
               GetMem例程(BitmapBits,BitmapSize);
               InternalGetDIB
                     (Bitmap.Handle,0,BITMAPINFO ^,BitmapBits ^,pf8bit);               //在第一次通过,设置流格式。
               若i = 0,则
                  如果(AVIStreamSetFormat(pStream,0,BITMAPINFO,BitmapInfoSize)LT;&GT; AVIERR_OK),那么
                      提高Exception.Create('无法设置AVI流格式');               //写入帧到视频流
               AVIERR:=
                  AVIStreamWrite(pStream,我,1,BitmapBits,BitmapSize,AVIIF_KEYFRAME,
                             Samples_Written,Bytes_Written);
               如果AVIERR&LT;&GT; AVIERR_OK然后
                    提高Exception.Create
                            ('无法添加相框为AVI。错误='
                               + INTTOHEX(AVIERR,8));
             最后
               如果(BITMAPINFO&LT;&GT;无),然后
                 freemem在(BITMAPINFO);
               如果(BitmapBits&LT;&GT;无),然后
                 freemem在(BitmapBits);
             结束;
          结束;          //创建从pStream可编辑视频流。
          如果CreateEditableStream(视频流,pStream)LT;&GT; AVIERR_OK然后
                    提高Exception.Create
                            (无法创建视频流');
       最后
          AviStreamRelease(pStream);
       结束;    最后
      Bitmap.free;
    结束;
结束;程序TAviWriter.AddAudio;
VAR
   与InputFile:PAVIFILE;
   的InputStream:PAVIStream;
   错误:字符串;
   OK:Int64的;
开始
   //打开的音频文件。
    OK:= AVIFileOpen(inputFile,请PChar类型(WavFileName),OF_READ,无);
    如果正常= AVIERR_BADFORMAT再犯错:='文件无法读取,表示文件损坏或无法识别的格式。;
    如果正常= AVIERR_MEMORY再犯错:='的文件不能因为内存不足开。;
    如果正常= AVIERR_FILEREAD则错误:在读取文件时发生了磁盘错误。'=;
    如果正常= AVIERR_FILEOPEN则错误:打开文件时发生磁盘错误。'=;
    如果正常= REGDB_E_CLASSNOTREG再犯错:='根据注册表,文件中AVIFileOpen指定的类型没有一个处理程序处理它。;
    如果犯错&LT;&GT; ''再养Exception.Create(ERR);   //打开音频流。
   尝试
     如果(AVIFileGetStream(inputFile,请的InputStream,0,0)下;&GT; AVIERR_OK)然后
         提高Exception.Create('无法获取音频流');     尝试
       //创建语音串流为InputStream的副本
       如果(CreateEditableStream(语音串流,为InputStream)LT;&GT; AVIERR_OK),那么
            提高Exception.Create(无法创建可编辑的AVI音频流');
     最后
       AviStreamRelease(InputStream的);
     结束;   最后
     AviFileRelease(与InputFile);
   结束;
结束;// --------------
// InternalGetDIB
// --------------
//位图以指定的PixelFormat的一个DIB转换。
//
//注意:InternalGetDIBSizes函数可以用来计算
//将BITMAPINFO位和缓冲区的大小nescessary。
//
//从graphics.pas,优化为我所用功能TAviWriter.InternalGetDIB

   位图:HBITMAP; //源位图的句柄
   调色板:HPALETTE; //源面板的手柄
   VAR BITMAPINFO; //将接收DIB的TBitmapInfo结构的缓冲区。
                      //足够大小的缓冲区必须被分配到前
                      //调用这个函数
   VAR位; //将接收DIB的像素数据的缓冲区
   的PixelFormat:TPixelFormat //目的地DIB的像素格式
):布尔; //真正的成功,失败返回FALSE
VAR
  OldPal:HPALETTE;
  DC:HDC;
开始
  InitializeBitmapInfoHeader(位图,TBitmapInfoHeader(BITMAPINFO)的PixelFormat);
  OldPal:= 0;
  直流:= CreateCompatibleDC(0);
  尝试
    如果(调色板&所述;大于0),那么
    开始
      OldPal:= SelectPalette(DC,调色板,FALSE);
      RealizePalette(DC);
    结束;
    结果:=(的GetDIBits(DC,位图,0,ABS(TBitmapInfoHeader(BITMAPINFO).biHeight)
      @Bits,TBitmapInfo(BITMAPINFO),DIB_RGB_COLORS)LT;&GT; 0);
  最后
    如果(OldPal&所述;大于0),那么
      SelectPalette(DC,OldPal,FALSE);
    DeleteDC(DC);
  结束;
结束;
// -------------------
// InternalGetDIBSizes
// -------------------
//计算缓冲区大小为nescessary位图的皈依到DIB
//指定的PixelFormat的。
//获取更多信息,请参见GetDIBSizes API函数。
//从graphics.pas,优化为我所用程序TAviWriter.InternalGetDIBSizes

   位图:HBITMAP; //源位图的句柄
   VAR InfoHeaderSize:整数; //缓冲区返回的大小,将接收
                                // DIB的TBitmapInfo结构
   VAR IMAGESIZE:LONGINT; //缓冲区的大小返回将接收DIB的像素数据
   的PixelFormat:TPixelFormat //目的地DIB的像素格式
);
VAR
  信息:TBitmapInfoHeader;
开始
  InitializeBitmapInfoHeader(位图,信息,的PixelFormat);
  //检查调色板设备格式
  如果(Info.biBitCount→8)然后
  开始
    //头,但没有调色板
    InfoHeaderSize:=一下SizeOf(TBitmapInfoHeader);
    如果((Info.biCom pression和BI_BITFIELDS)所述;大于0),那么
      公司(InfoHeaderSize,12);
  其他结束
    //头和调色板
    InfoHeaderSize:=一下SizeOf(TBitmapInfoHeader)+一下SizeOf(TRGBQuad)*(1 SHL Info.biBitCount);
  IMAGESIZE:= Info.biSizeImage;
结束;// --------------------------
// InitializeBitmapInfoHeader
// --------------------------
//当转换为一个填充用位图的值的TBitmapInfoHeader
//指定的PixelFormat的DIB。
//从graphics.pas,优化为我所用程序TAviWriter.InitializeBitmapInfoHeader

   位图:HBITMAP; //源位图的句柄
   VAR信息:TBitmapInfoHeader; //该TBitmapInfoHeader缓冲区,将接收到的值
   的PixelFormat:TPixelFormat //目的地DIB的像素格式
);
VAR
  DIB:TDIBSection;
  字节:整数;
  功能AlignBit(位,BitsPerPixel,阵营:红衣主教):红衣主教;
  开始
    DEC(校准);
    结果:=((位* BitsPerPixel)+对齐),而不是对准;
    结果:=结果SHR 3;
  结束;
开始
  DIB.dsbmih.biSize:= 0;
  字节:= GetObject的(位图,一下SizeOf(DIB),@DIB);
  如果(字节= 0),那么
    提高Exception.Create('无效的位图');
//错误(sInvalidBitmap);  如果(字节&GT; =(sizeof的(DIB.dsbm)+ sizeof的(DIB.dsbmih)))和
    (DIB.dsbmih.biSize&GT; = sizeof的(DIB.dsbmih)),然后
    信息:= DIB.dsbmih
  其他
  开始
    FillChar(信息,sizeof的(信息),0);
    与信息,DIB.dsbm做
    开始
      biSize:=一下SizeOf(信息);
      biWidth:= bmWidth;
      biHeight:= bmHeight;
    结束;
  结束;
  时的PixelFormat
    pf1bit:Info.biBitCount:= 1;
    pf4bit:Info.biBitCount:= 4;
    pf8bit:Info.biBitCount:= 8;
    pf24bit:Info.biBitCount:= 24;
  其他
//错误(sInvalidPixelFormat);
    提高Exception.Create('无效的像素格式');
    // Info.biBitCount:= DIB.dsbm.bmBitsPixel * DIB.dsbm.bmPlanes;
  结束;
  Info.biPlanes:= 1;
  Info.biCom pression:= BI_RGB; //始终在RGB格式返回数据
  Info.biSizeImage:= AlignBit(Info.biWidth,Info.biBitCount,32)*红衣主教(ABS(Info.biHeight));
结束;程序TAviWriter.SetWavFileName(价值:字符串);
开始
   如果小写(fWavFileName)LT;&GT;小写字母(值)
      那么如果小写(ExtractFileExt(值))&LT;&GT; .WAV
             然后抬起Exception.Create('WavFileName必须命名一个文件
                             +'与.WAV扩展名)
             否则fWavFileName:=值;
结束;程序注册;
开始
  RegisterComponents('样品',[TAviWriter]);
结束;结束。


更改的 AVISaveV 功能,它的统一code版本。当在Windows API的参考函数的说明的Uni code和ANSI名字对您来说意味着,在Delphi中,你要选择无论是从统一code版的功能,或从ANSI之一取决于你会使用什么样的编译器。

您正在试图调用 AVISaveV ,它实际并不存在。这里只有 AVISaveVA AVISaveVW avifil32.dll 和既然你要这个code转换为统一code,尝试改变函数导入是这样的:

 功能AVISaveV;外部avifil32.dll'名'AVISaveVW';

这仅仅是第一思想,code的定义,就像是甚至不能在Delphi中的非统一code版本的工作,因为它称为不存在的功能。

My application creates images from fractals and I love the feeling of 'flying' around a fractal. I once saved about 2000 bitmaps to file and created an AVI from it using Premiere. That experience is rather frustrating though I succeeded in creating a movie. That was spectacular. Of course I want to create a video from my application. I actually don't care about the niftyness of the codec, compression or whatever. I just want to have a video that I can replay on most systems.

In the past I have tried this but never succeeded. I was triggered by a question recently but alas could not get FFMpeg running.

Update

I decided to adapt the question slightly and put a bounty for it. I have seen several solutions but the most attractive (because it's simple) seems to me TAviWrite. I tried TAviWriter but did not succeed. In procedure TAviWriter.Write; the function call around line 370

  AVIERR := AVISaveV(s,
//                   pchar(FileName),
               nil,                    // File handler
               nil,                    // Callback
               nStreams,               // Number of streams
               Streams,
               CompOptions);           // Compress options for VideoStream

does not return AVIERR_OK.

Update 2

The reason for above mentioned error is a wrong declaration of AVISaveV, it should be declared as AVISaveVW as TLama pointed out. The correct code for creating AVI filoes form BMP files is posted below. The original code below was downloaded from efg with an example unit.

Using Delphi XE on Windows 7.

unit AviWriter;

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//       AviWriter -- a component to create rudimentary AVI files          //
//                  by Elliott Shevin, with large pieces of code           //
//                  stolen from Anders Melander                            //
//       version 1.0. Please send comments, suggestions, and advice        //
//       to shevine@aol.com.                                               //
/////////////////////////////////////////////////////////////////////////////

interface

uses
  Windows,Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ole2;

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                      Video for Windows                                     //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// Adapted from Thomas Schimming's VFW.PAS                                    //
// (c) 1996 Thomas Schimming, schimmin@iee1.et.tu-dresden.de                  //
// (c) 1998,99 Anders Melander                                                //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// Ripped all COM/ActiveX stuff and added some AVI stream functions.          //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
// Unicode version created by Arnold and TLama (2012)                         //
////////////////////////////////////////////////////////////////////////////////

type
  LONG = Longint;
  PVOID = Pointer;

const
// TAVIFileInfo dwFlag values
   AVIF_HASINDEX          = $00000010;
   AVIF_MUSTUSEINDEX      = $00000020;
   AVIF_ISINTERLEAVED     = $00000100;
   AVIF_WASCAPTUREFILE    = $00010000;
   AVIF_COPYRIGHTED       = $00020000;
   AVIF_KNOWN_FLAGS       = $00030130;

   AVIERR_UNSUPPORTED     = $80044065; // MAKE_AVIERR(101)
   AVIERR_BADFORMAT       = $80044066; // MAKE_AVIERR(102)
   AVIERR_MEMORY          = $80044067; // MAKE_AVIERR(103)
   AVIERR_INTERNAL        = $80044068; // MAKE_AVIERR(104)
   AVIERR_BADFLAGS        = $80044069; // MAKE_AVIERR(105)
   AVIERR_BADPARAM        = $8004406A; // MAKE_AVIERR(106)
   AVIERR_BADSIZE         = $8004406B; // MAKE_AVIERR(107)
   AVIERR_BADHANDLE       = $8004406C; // MAKE_AVIERR(108)
   AVIERR_FILEREAD        = $8004406D; // MAKE_AVIERR(109)
   AVIERR_FILEWRITE       = $8004406E; // MAKE_AVIERR(110)
   AVIERR_FILEOPEN        = $8004406F; // MAKE_AVIERR(111)
   AVIERR_COMPRESSOR      = $80044070; // MAKE_AVIERR(112)
   AVIERR_NOCOMPRESSOR    = $80044071; // MAKE_AVIERR(113)
   AVIERR_READONLY        = $80044072; // MAKE_AVIERR(114)
   AVIERR_NODATA          = $80044073; // MAKE_AVIERR(115)
   AVIERR_BUFFERTOOSMALL  = $80044074; // MAKE_AVIERR(116)
   AVIERR_CANTCOMPRESS    = $80044075; // MAKE_AVIERR(117)
   AVIERR_USERABORT       = $800440C6; // MAKE_AVIERR(198)
   AVIERR_ERROR           = $800440C7; // MAKE_AVIERR(199)

// TAVIStreamInfo dwFlag values
   AVISF_DISABLED         = $00000001;
   AVISF_VIDEO_PALCHANGES = $00010000;
   AVISF_KNOWN_FLAGS      = $00010001;

type
  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;

  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: DWORD;
    szName:  array[0..63] of WideChar;
  end;
  TAVIStreamInfo = TAVIStreamInfoW;
  PAVIStreamInfo = ^TAVIStreamInfo;

  PAVIStream = pointer;
  PAVIFile   = pointer;
  TAVIStreamList = array[0..0] of PAVIStream;
  PAVIStreamList = ^TAVIStreamList;
  TAVISaveCallback = function (nPercent: integer): LONG; stdcall;

  TAVICompressOptions = packed record
    fccType     : DWORD;
    fccHandler      : DWORD;
    dwKeyFrameEvery : DWORD;
    dwQuality       : DWORD;
    dwBytesPerSecond    : DWORD;
    dwFlags     : DWORD;
    lpFormat        : pointer;
    cbFormat        : DWORD;
    lpParms     : pointer;
    cbParms     : DWORD;
    dwInterleaveEvery   : DWORD;
  end;
  PAVICompressOptions = ^TAVICompressOptions;

// Palette change data record
const
  RIFF_PaletteChange: DWORD = 1668293411;

type
  TAVIPalChange = packed record
    bFirstEntry     : byte;
    bNumEntries     : byte;
    wFlags      : WORD;
    peNew       : array[byte] of TPaletteEntry;
  end;
  PAVIPalChange = ^TAVIPalChange;

  APAVISTREAM          = array[0..1] of PAVISTREAM;
  APAVICompressOptions = array[0..1] of PAVICompressOptions;


procedure AVIFileInit; stdcall;
procedure AVIFileExit; stdcall;
function AVIFileOpen(var ppfile: PAVIFile; szFile: PChar; uMode: UINT; lpHandler: pointer): HResult; stdcall;
function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVISTREAM; var psi: TAVIStreamInfo): HResult; stdcall;
function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; cbFormat: LONG): HResult; stdcall;
function AVIStreamReadFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; var cbFormat: LONG): HResult; stdcall;
function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: pointer; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; stdcall;
function AVIStreamRelease(pavi: PAVISTREAM): ULONG; stdcall;
function AVIFileRelease(pfile: PAVIFile): ULONG; stdcall;
function AVIFileGetStream(pfile: PAVIFile; var ppavi: PAVISTREAM; fccType: DWORD; lParam: LONG): HResult; stdcall;
function CreateEditableStream(var ppsEditable: PAVISTREAM; psSource: PAVISTREAM): HResult; stdcall;
function AVISaveV(szFile: PChar; pclsidHandler: PCLSID; lpfnCallback: TAVISaveCallback;
  nStreams: integer; pavi: APAVISTREAM; lpOptions: APAVICompressOptions): HResult; stdcall;

const
  AVIERR_OK       = 0;

  AVIIF_LIST      = $01;
  AVIIF_TWOCC     = $02;
  AVIIF_KEYFRAME  = $10;

  streamtypeVIDEO = $73646976; // DWORD( 'v', 'i', 'd', 's' )
  streamtypeAUDIO = $73647561; // DWORD( 'a', 'u', 'd', 's' )


type
  TPixelFormat = (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom);

type
  TAviWriter = class (TComponent)
  private
    TempFileName   : string;
    pFile          : PAVIFile;
    fHeight        : integer;
    fWidth         : integer;
    fStretch       : boolean;
    fFrameTime     : integer;
    fFileName      : string;
    fWavFileName   : string;
    VideoStream    : PAVISTREAM;
    AudioStream    : PAVISTREAM;

    procedure AddVideo;
    procedure AddAudio;
    procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
        var ImageSize: longInt; PixelFormat: TPixelFormat);
    function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
        var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean;
    procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader;
           PixelFormat: TPixelFormat);
    procedure SetWavFileName(value : string);

  public
    Bitmaps : TList;
    constructor Create(AOwner : TComponent); override;
    destructor  Destroy; override;
    procedure Write;

  published
    property Height   : integer read fHeight  write fHeight;
    property Width    : integer read fWidth   write fWidth;
    property FrameTime: integer read fFrameTime write fFrameTime;
    property Stretch  : boolean read fStretch write fStretch;
    property FileName : string  read fFileName write fFileName;
    property WavFileName  : string  read fWavFileName write SetWavFileName;
  end;

procedure Register;

implementation

procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit';
procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit';
function AVIFileOpen; external 'avifil32.dll' name 'AVIFileOpenW';
function AVIFileCreateStream; external 'avifil32.dll' name 'AVIFileCreateStreamW';
function AVIStreamSetFormat; external 'avifil32.dll' name 'AVIStreamSetFormat';
function AVIStreamReadFormat; external 'avifil32.dll' name 'AVIStreamReadFormat';
function AVIStreamWrite; external 'avifil32.dll' name 'AVIStreamWrite';
function AVIStreamRelease; external 'avifil32.dll' name 'AVIStreamRelease';
function AVIFileRelease; external 'avifil32.dll' name 'AVIFileRelease';
function AVIFileGetStream; external 'avifil32.dll' name 'AVIFileGetStream';
function CreateEditableStream; external 'avifil32.dll' name 'CreateEditableStream';
function AVISaveV; external 'avifil32.dll' name 'AVISaveVW';

constructor TAviWriter.Create(AOwner : TComponent);
begin
    inherited Create(AOwner);
    fHeight    := screen.height div 10;
    fWidth     := screen.width  div 10;
    fFrameTime := 1000;
    fStretch   := true;
    fFileName  := '';
    Bitmaps    := TList.create;
    AVIFileInit;
    TempFileName := {tempdir +} 'temp.avi';
end;

destructor TAviWriter.Destroy;
begin
    Bitmaps.free;
    AviFileExit;
    inherited;
end;

procedure TAviWriter.Write;
var
  ExtBitmap             : TBitmap;
  nstreams              : integer;
  i                     : integer;
  Streams               : APAVISTREAM;
  CompOptions           : APAVICompressOptions;
  AVIERR                : integer;
  refcount              : integer;
begin
   AudioStream := nil;
   VideoStream := nil;

   // If no bitmaps are on the list, raise an error.
   if Bitmaps.count < 1
      then raise Exception.Create('No bitmaps on the Bitmaps list');

   // If anything on the Bitmaps TList is not a bitmap, raise
   // an error.
   for i := 0 to Bitmaps.count - 1 do
   begin
      ExtBitmap := Bitmaps[i];
      if not(ExtBitmap is TBitmap)
         then raise Exception.Create('Bitmaps[' + inttostr(i)
                       + '] is not a TBitmap');
   end; // for

   try
      AddVideo;

      if WavFileName <> ''
         then AddAudio;

      // Create the output file.
      if WavFileName <> ''
         then nstreams := 2
         else nstreams := 1;

      Streams[0] := VideoStream;
      Streams[1] := AudioStream;
      CompOptions[0] := nil;
      CompOptions[1] := nil;

      AVIERR := AVISaveV(
                   pchar(FileName),
                   nil,                    // File handler
                   nil,                    // Callback
                   nStreams,               // Number of streams
                   Streams,
                   CompOptions);           // Compress options for VideoStream
      if AVIERR <> AVIERR_OK then
             raise Exception.Create('Unable to write output file');
   finally
      if assigned(VideoStream)
         then AviStreamRelease(VideoStream);
      if assigned(AudioStream)
         then AviStreamRelease(AudioStream);

      try
         repeat
            refcount := AviFileRelease(pFile);
         until refcount <= 0;
      except
         // ignore exception
      end; // try..except

      DeleteFile(TempFileName);
   end; // try..finally
end;

procedure TAviWriter.AddVideo;
var
  Pstream:         PAVISTREAM;
  StreamInfo:      TAVIStreamInfo;
  BitmapInfo:      PBitmapInfoHeader;
  BitmapInfoSize:  Integer;
  BitmapSize:      longInt;
  BitmapBits:      pointer;
  Bitmap:          TBitmap;
  ExtBitmap:       TBitmap;
  Samples_Written: LONG;
  Bytes_Written:   LONG;
  AVIERR:          integer;
  i:               integer;
  ok: Int64;
  mode: uInt32;
  fn: pChar;
  err: string;
begin
    // Open AVI file for write
    pfile := nil;
    mode  := OF_CREATE or OF_WRITE or OF_SHARE_EXCLUSIVE;
    fn    := pchar (TempFileName);

    ok := AVIFileOpen (pFile, fn, mode, nil);
    if ok = AVIERR_BADFORMAT    then err := 'The file could not be read, indicating a corrupt file or an unrecognized format.';
    if ok = AVIERR_MEMORY       then err := 'The file could not be opened because of insufficient memory.';
    if ok = AVIERR_FILEREAD     then err := 'A disk error occurred while reading the file.';
    if ok = AVIERR_FILEOPEN     then err := 'A disk error occurred while opening the file.';
    if ok = REGDB_E_CLASSNOTREG then err := 'According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it.';
    if err <> '' then raise Exception.Create (err);

    // Allocate the bitmap to which the bitmaps on the Bitmaps Tlist
    // will be copied.
    Bitmap        := TBitmap.create;
    Bitmap.Height := self.Height;
    Bitmap.Width  := self.Width;

    // Write the stream header.
    try
       FillChar (StreamInfo, sizeof (StreamInfo), 0);

       // Set frame rate and scale
       StreamInfo.dwRate  := 1000;
       StreamInfo.dwScale := fFrameTime;
       StreamInfo.fccType := streamtypeVIDEO;
       StreamInfo.fccHandler := 0;
       StreamInfo.dwFlags := 0;
       StreamInfo.dwSuggestedBufferSize := 0;
       StreamInfo.rcFrame.Right  := self.width;
       StreamInfo.rcFrame.Bottom := self.height;

       // Open AVI data stream
       if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then
           raise Exception.Create('Failed to create AVI video stream');

       try
          // Write the bitmaps to the stream.
          for i := 0 to Bitmaps.count - 1 do
          begin
             BitmapInfo := nil;
             BitmapBits := nil;
             try

               // Copy the bitmap from the list to the AVI bitmap,
               // stretching if desired. If the caller elects not to
               // stretch, use the first pixel in the bitmap as a
               // background color in case either the height or
               // width of the source is smaller than the output.
               // If Draw fails, do a StretchDraw.
               ExtBitmap := Bitmaps[i];
               if fStretch
                  then Bitmap.Canvas.StretchDraw
                           (Rect(0,0,self.width,self.height),ExtBitmap)
                  else try
                         with Bitmap.Canvas do begin
                            Brush.Color := ExtBitmap.Canvas.Pixels[0,0];
                            Brush.Style := bsSolid;
                            FillRect(Rect(0,0,Bitmap.Width,Bitmap.Height));
                            Draw(0,0,ExtBitmap);
                         end;
                       except
                         Bitmap.Canvas.StretchDraw
                            (Rect(0,0,self.width,self.height),ExtBitmap);
                       end;

               // Determine size of DIB
               InternalGetDIBSizes(Bitmap.Handle, BitmapInfoSize, BitmapSize, pf8bit);
               if (BitmapInfoSize = 0) then
                  raise Exception.Create('Failed to retrieve bitmap info');

               // Get DIB header and pixel buffers
               GetMem(BitmapInfo, BitmapInfoSize);
               GetMem(BitmapBits, BitmapSize);
               InternalGetDIB
                     (Bitmap.Handle, 0, BitmapInfo^, BitmapBits^, pf8bit);

               // On the first time through, set the stream format.
               if i = 0 then
                  if (AVIStreamSetFormat(pStream, 0, BitmapInfo, BitmapInfoSize) <> AVIERR_OK) then
                      raise Exception.Create('Failed to set AVI stream format');

               // Write frame to the video stream
               AVIERR :=
                  AVIStreamWrite(pStream, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME,
                             Samples_Written, Bytes_Written);
               if AVIERR <> AVIERR_OK then
                    raise Exception.Create
                            ('Failed to add frame to AVI. Err='
                               + inttohex(AVIERR,8));
             finally
               if (BitmapInfo <> nil) then
                 FreeMem(BitmapInfo);
               if (BitmapBits <> nil) then
                 FreeMem(BitmapBits);
             end;
          end;

          // Create the editable VideoStream from pStream.
          if CreateEditableStream(VideoStream,pStream) <> AVIERR_OK then
                    raise Exception.Create
                            ('Could not create Video Stream');
       finally
          AviStreamRelease(pStream);
       end;

    finally
      Bitmap.free;
    end;
end;

procedure TAviWriter.AddAudio;
var
   InputFile    : PAVIFILE;
   InputStream  : PAVIStream;
   err: string;
   ok: Int64;
begin
   // Open the audio file.
    ok := AVIFileOpen(InputFile, pchar(WavFileName),OF_READ, nil);
    if ok = AVIERR_BADFORMAT    then err := 'The file could not be read, indicating a corrupt file or an unrecognized format.';
    if ok = AVIERR_MEMORY       then err := 'The file could not be opened because of insufficient memory.';
    if ok = AVIERR_FILEREAD     then err := 'A disk error occurred while reading the file.';
    if ok = AVIERR_FILEOPEN     then err := 'A disk error occurred while opening the file.';
    if ok = REGDB_E_CLASSNOTREG then err := 'According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it.';
    if err <> '' then raise Exception.Create (err);

   // Open the audio stream.
   try
     if (AVIFileGetStream(InputFile, InputStream, 0, 0) <> AVIERR_OK) then
         raise Exception.Create('Unable to get audio stream');

     try
       // Create AudioStream as a copy of InputStream
       if (CreateEditableStream(AudioStream,InputStream) <> AVIERR_OK) then
            raise Exception.Create('Failed to create editable AVI audio stream');
     finally
       AviStreamRelease(InputStream);
     end;

   finally
     AviFileRelease(InputFile);
   end;
end;

// --------------
// InternalGetDIB
// --------------
// Converts a bitmap to a DIB of a specified PixelFormat.
//
// Note: The InternalGetDIBSizes function can be used to calculate the
// nescessary sizes of the BitmapInfo and Bits buffers.
//
// From graphics.pas, "optimized" for our use

function TAviWriter.InternalGetDIB
(
   Bitmap: HBITMAP;   // The handle of the source bitmap
   Palette: HPALETTE; // The handle of the source palette
   var BitmapInfo;    // The buffer that will receive the DIB's TBitmapInfo structure.
                      // A buffer of sufficient size must have been allocated prior to
                      // calling this function
   var Bits;          // The buffer that will receive the DIB's pixel data
   PixelFormat: TPixelFormat // The pixel format of the destination DIB
): Boolean; // True on success, False on failure
var
  OldPal    : HPALETTE;
  DC        : HDC;
begin
  InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), PixelFormat);
  OldPal := 0;
  DC := CreateCompatibleDC(0);
  try
    if (Palette <> 0) then
    begin
      OldPal := SelectPalette(DC, Palette, False);
      RealizePalette(DC);
    end;
    Result := (GetDIBits(DC, Bitmap, 0, abs(TBitmapInfoHeader(BitmapInfo).biHeight),
      @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0);
  finally
    if (OldPal <> 0) then
      SelectPalette(DC, OldPal, False);
    DeleteDC(DC);
  end;
end;


// -------------------
// InternalGetDIBSizes
// -------------------
// Calculates the buffer sizes nescessary for convertion of a bitmap to a DIB
// of a specified PixelFormat.
// See the GetDIBSizes API function for more info.
// From graphics.pas, "optimized" for our use

procedure TAviWriter.InternalGetDIBSizes
(
   Bitmap: HBITMAP;             // The handle of the source bitmap
   var InfoHeaderSize: Integer; // The returned size of a buffer that will receive
                                // the DIB's TBitmapInfo structure
   var ImageSize: longInt;      // The returned size of a buffer that will receive the DIB's pixel data
   PixelFormat: TPixelFormat    // The pixel format of the destination DIB
);
var
  Info: TBitmapInfoHeader;
begin
  InitializeBitmapInfoHeader(Bitmap, Info, PixelFormat);
  // Check for palette device format
  if (Info.biBitCount > 8) then
  begin
    // Header but no palette
    InfoHeaderSize := SizeOf(TBitmapInfoHeader);
    if ((Info.biCompression and BI_BITFIELDS) <> 0) then
      Inc(InfoHeaderSize, 12);
  end else
    // Header and palette
    InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl Info.biBitCount);
  ImageSize := Info.biSizeImage;
end;

// --------------------------
// InitializeBitmapInfoHeader
// --------------------------
// Fills a TBitmapInfoHeader with the values of a bitmap when converted to a
// DIB of a specified PixelFormat.
// From graphics.pas, "optimized" for our use

procedure TAviWriter.InitializeBitmapInfoHeader
(
   Bitmap: HBITMAP;              // The handle of the source bitmap
   var Info: TBitmapInfoHeader;  // The TBitmapInfoHeader buffer that will receive the values
   PixelFormat: TPixelFormat     // The pixel format of the destination DIB
);
var
  DIB       : TDIBSection;
  Bytes     : Integer;
  function AlignBit(Bits, BitsPerPixel, Alignment: Cardinal): Cardinal;
  begin
    Dec(Alignment);
    Result := ((Bits * BitsPerPixel) + Alignment) and not Alignment;
    Result := Result SHR 3;
  end;
begin
  DIB.dsbmih.biSize := 0;
  Bytes := GetObject(Bitmap, SizeOf(DIB), @DIB);
  if (Bytes = 0) then
    raise Exception.Create('Invalid bitmap');
//    Error(sInvalidBitmap);

  if (Bytes >= (sizeof(DIB.dsbm) + sizeof(DIB.dsbmih))) and
    (DIB.dsbmih.biSize >= sizeof(DIB.dsbmih)) then
    Info := DIB.dsbmih
  else
  begin
    FillChar(Info, sizeof(Info), 0);
    with Info, DIB.dsbm do
    begin
      biSize := SizeOf(Info);
      biWidth := bmWidth;
      biHeight := bmHeight;
    end;
  end;
  case PixelFormat of
    pf1bit: Info.biBitCount := 1;
    pf4bit: Info.biBitCount := 4;
    pf8bit: Info.biBitCount := 8;
    pf24bit: Info.biBitCount := 24;
  else
//    Error(sInvalidPixelFormat);
    raise Exception.Create('Invalid pixel format');
    // Info.biBitCount := DIB.dsbm.bmBitsPixel * DIB.dsbm.bmPlanes;
  end;
  Info.biPlanes := 1;
  Info.biCompression := BI_RGB; // Always return data in RGB format
  Info.biSizeImage := AlignBit(Info.biWidth, Info.biBitCount, 32) * Cardinal(abs(Info.biHeight));
end;

procedure TAviWriter.SetWavFileName(value : string);
begin
   if lowercase(fWavFileName) <> lowercase(value)
      then if lowercase(ExtractFileExt(value)) <> '.wav'
             then raise Exception.Create('WavFileName must name a file '
                             + 'with the .wav extension')
             else fWavFileName := value;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TAviWriter]);
end;

end.

解决方案

Change the import part of the AVISaveV function to the Unicode version of it. When the function in the Windows API reference has the note Unicode and ANSI names it means for you, in Delphi, you have to choose either from the Unicode version of the function or from the ANSI one depending on what compiler will you use.

You're trying to call the AVISaveV, which physically doesn't exists. There's only AVISaveVA and the AVISaveVW in avifil32.dll and since you want to convert this code to Unicode, try to change the function import this way:

function AVISaveV; external 'avifil32.dll' name 'AVISaveVW';

This is just a first thought, the code with the definition like was cannot work even in non Unicode versions of Delphi, because it called the not existing function.

这篇关于如何转换位图视频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆