Mam's WebSite
建築CGパース住宅CGパース

Mamの覚書Q&A検索

トップページMamの覚書Q&A検索Delphi(API)⇒Q&A


大項目:「 Delphi 」 - 中項目:「 API 」

「 bmpファイルからAVIファイルを生成したい 」

タイトルのとおり、BMPファイルからAVIファイルを生成したい。


回答

まずは「 vfw.pas Delphi 」 などでググっていただき、
vfw.pas ファイルをなんとか取得してください。
4400行くらいのファイルです。
C++のvfw.hをDelphiに変換したものみたいです。
 
vfw.pasをパスの通ったフォルダなどに入れてください。
次に、Delphiを起動し
「ファイル⇒新規作成⇒VCLフォームアプリケーションDelphi」を選択し、
新規アプリケーションを作成します。
 
全て保存を押して、適当なフォルダに新規アプリケーションを保存します。
そのフォルダに、1.bmp 2.bmp 3.bmp 4.bmp 5.bmp 6.bmp
の6つのビットマップファイルを240×160のサイズでペイントなどを使って適当に作成してください。
6つのビットマップファイルは、少し絵が違うほうがわかりやすいです。
 
新規アプリケーションにボタンを1つ追加します。
新規アプリケーションのソースは以下です。
 
ボタンをクリックすると、圧縮形式を聞いてきて、
1.bmp 2.bmp 3.bmp 4.bmp 5.bmp 6.bmpファイルがa.aviファイルになります。

ソース

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,vfw, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;
procedure CreateAVI(Handle:THandle;filename:string;bmpList:TStringList);
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure CreateAVI(Handle:THandle;filename: string; bmpList: TStringList);
var
  i:integer;
  AviInfo:TAVISTREAMINFOW;
  compOpt:TAVICOMPRESSOPTIONS;
  pcompOpt:PAVICOMPRESSOPTIONS;
  ppFile:PAVIFile;
  ppAvi:PAVIStream;
  ppComp:PAVIStream;
  bmp:TBitmap;
  bmpI:PBitmapInfo;
  bmpBits:Pointer;
  infosize,imagesize:Cardinal;
begin
  //AviInfoの初期化
  ZeroMemory(@AviInfo,sizeof(AviInfo));
  //圧縮オプションの初期化
  ZeroMemory(@compOpt,sizeof(compOpt));
  //aviinfoの設定
  AviInfo.fccType:=streamtypeVIDEO;
  AviInfo.fccHandler:=mmioFOURCC('D','I','B',' ');
  AviInfo.dwFlags:=0;
  AviInfo.dwCaps:=0;
  AviInfo.wPriority:=0;
  AviInfo.wLanguage:=0;
  AviInfo.dwScale:=1;
  AviInfo.dwRate:=1;
  AviInfo.dwStart:=0;
  AviInfo.dwLength:=bmpList.Count;
  AviInfo.dwInitialFrames:=0;
  AviInfo.dwSuggestedBufferSize:=0;
  AviInfo.dwQuality:=DWORD(-1); //デフォルト
  AviInfo.dwSampleSize:=0;
  AviInfo.rcFrame:=Rect(0,0,240,160);
  AviInfo.dwEditCount:=0;
  AviInfo.dwFormatChangeCount:=0;
  AviInfo.szName:='';
  //デフォルトで未圧縮を設定
  compOpt.fccHandler:=541215044;
 
  if FileExists(filename) then
    DeleteFile(filename);
 
  //vfwの初期化
  AVIFileInit;
  //AVIファイルを開く
  AVIFileOpenW(ppFile,PWideChar(filename),
    OF_WRITE or OF_CREATE or OF_SHARE_DENY_NONE,nil);
  //ストリームの作成
  AVIFileCreateStream(ppfile,ppAvi,@AviInfo);
 
  pcompOpt:=@compOpt;
  AVISaveOptions(Handle,
    ICMF_CHOOSE_DATARATE or
    ICMF_CHOOSE_KEYFRAME or
    ICMF_CHOOSE_PREVIEW
    ,1,ppAvi,pcompOpt);
  AVISaveOptionsFree(1,pcompOpt);
 
  //圧縮ストリームの作成
  AVIMakeCompressedStream(ppComp,ppAvi,pcompOpt,nil);
 
  bmp:=TBitmap.Create;
  for i := 0 to bmpList.Count-1 do
  begin
    bmp.LoadFromFile(bmpList[i]);
    bmp.PixelFormat:=pf24bit;
    bmp.Dormant;  //イメージを DIB 形式に
    GetDIBSizes(bmp.Handle,infosize,imagesize); //サイズ取得
    bmpI:=AllocMem(infosize);  //メモリを割り当てる
    bmpBits:=AllocMem(imagesize);  //メモリを割り当てる
    //ヘッダー(PBitmapInfo)とイメージを返します。
    GetDIB(Bmp.Handle,bmp.Palette,bmpI^,bmpBits^);
 
    //1枚目のBitmapをWireteする直前にBitmapInfoを送り込む
    if i=0 then
    begin
      AVIStreamSetFormat(ppComp,0,bmpI,infosize);
    end;
 
    AVIStreamWrite(ppcomp,i,1,bmpBits,imagesize,AVIIF_KEYFRAME,nil,nil);
    Freemem(bmpI);
    Freemem(bmpBits);
  end;
  bmp.Free;
 
  AVIStreamRelease(ppAvi);
  AVIStreamRelease(ppComp);
  AVIFileRelease(ppFile);
 
  AVIFileExit;
end;
 

procedure TForm1.Button1Click(Sender: TObject);
var stl:TStringList;
    filename:string;
    path:string;
begin
  path:=ExtractFilePath(application.ExeName);
  stl:=TStringList.Create;
 
  stl.Add(path+'1.bmp');
  stl.Add(path+'2.bmp');
  stl.Add(path+'3.bmp');
  stl.Add(path+'4.bmp');
  stl.Add(path+'5.bmp');
  stl.Add(path+'6.bmp');
  filename:=path+'a.avi';
  CreateAVI(Handle,filename,stl);
 
  stl.Free;
end;
 

end.


Mam's WebSite