複数BMP画像の動画(AVI)変換

複数のビットマップ画像を動画(AVI)へ変換する例です(Video for Windows(VFW)のAPIを多用していますので、Windows以外のOSへの応用は無理です^^)。適当なフォルダ内に番号付きの画像を複数作成し、コマンドラインにより画像の名前、フレームレート(1秒間当たりの画像の枚数)等を指定すれば下図のような動画ファイルが作成されます。今回の例では、音声の入力には対応していません。

コンパイル時にはVFW用のヘッダ・ライブラリが必要となりますが、標準の gcc/cygwin には付属していない場合があります。また、MinGW に標準で付属のVFWでも、現段階では不具合が発生するようなので、インターネット等よりダウンロードする必要があります。

VFWに必要なヘッダを以下に示します。VC++, Boland C++ をお持ちの方はそれぞれの Include ファイル内にこれらのヘッダが付属されていますので、そのまま適当なフォルダ(/usr/include/w32api/ etc.)にコピーして下さい。

ファイル名 コメント
msacmh.h Audio Compression Manager
mmreg.h Multimedia Registration
vfw.h Video for windows
vfwmsgs.h error codes
verinfo.h version info
verinfo.ver used by resource files has to be changed
digitalv.h MCI Digital Video Command Set 

ライブラリは、本来であればMinGW に付属のライブラリ(libvfw32.a)の一つで十分ですが、このファイルでは不具合が発生するようなので、multilib.zip を利用して下さい。このファイルには3つのライブラリが入っており、それぞれ異なるDLLへリンクされています。3つのライブラリは適当なフォルダ(/usr/lib/w32api/ etc.c)にコピーし、利用して下さい。AVIを読込み・作成する場合は libvfw_avi32.a を利用します。後のライブラリは今回は使用していません。

プログラムリンク例:
Gami[454]% gcc -o bmp2avi bmp2avi.c -lvfw_avi32

VFWのAPIにより、画像を圧縮しながらAVIを作成するようになっています。圧縮は

AVICOMPRESSOPTIONS opt;
opt.fccHandler = mmioFOURCC('m','s','v','c');
というようにコード名を指定し圧縮方法を選択します。コード名は下記のようなものがあります。

コード名 16進数字 Property Desc. Full Title
"cvid" "63766964" Cinepak Codec Cinepak Codec by Radius
"iv32" "69763332" IR32 Intel Indeo Video R3.2
"msvc" "6D737663" MS-CRAM Microsoft Video 1
"mrle" "6D726C65" MS-RLE Microsoft RLE
"yvu9" "79767539" Raw Intel Indeo Video Raw R1.1
"iv50" "69763530" Intel Video 5 Intel Video 5.04
"vdom" "76646F6D" VDOWave VDOnet VDOWave
"mpv4" "6D707634" MS-MPEG4V1 MS MPEG-4 Video Codec V1
"mp42" "6D703432" MS-MPEG4V2 MS MPEG-4 Video Codec V2
"I263" "49323633" I.263 V2.55 Intel I.263 Video Driver 2.55.012
"iv41" "69763431" IR41 Intel Indeo Video Interactive
Nulls "00000000" Uncompressed No Compression

作成時の引数 AVIファイル
Gami[454]% ls
bmp2avi.c  bmp2avi.exe*  bmp2avi.h  img/  makefile
Gami[455]% ls img
cat00.bmp  cat01.bmp  cat02.bmp  cat03.bmp  cat04.bmp  cat05.bmp
Gami[456]% bmp2avi.exe -f 1 -o cat.avi img/cat
Gami[457]% ls
bmp2avi.c  bmp2avi.exe*  bmp2avi.h  cat.avi  img/  makefile
Gami[458]% bmp2avi
USAGE: bmp2avi rootname [options]
        rootname: the root name for the .BMP files.
option:
        -I interlace is on. Odd  lines first
        -i interlace is on. Even lines first
        -f frames by second (30 by default)
        -d delete files after include (use with care)
        -o output filename ([out.avi] if not given)
        -s first image indice (if not zero)
Gami[459]%

 ダウンロード

複数BMP画像の動画(AVI)変換(bmp2avi.cpp)
//-----------------------------------------------------------------
// bmp2avi.c:
//      BMP files to AVI stream
//                 Last Update: <2005/01/19 17:41:20 A.Murakami>
//-----------------------------------------------------------------
#include <stdio.h>
#include "bmp2avi.h"
//-----------------------------------------------------------------
#pragma comment(lib,"vfw32")
//-----------------------------------------------------------------
int main(int argc,char *argv[])
{
    int i,prefix=0;
    AviInfo avi;
    init_avi(&avi);
    //--------------------------------------------------
    // 引数読込み
    //--------------------------------------------------
    for(i=1;i<argc;i++){
        if(argv[i][0] == '-'){
            switch(argv[i][1]){
            case 'h': usage(argv[0]);      break;
            case 'i': avi.interlace = -1;  break;
            case 'I': avi.interlace = +1;  break;
            case 'd': avi.deleteAfter = 1; break;
            case 'f': avi.framesPerSecond = getIntArg(argv,&i); break;
            case 'o': strcpy(avi.FileName,getArg(argv,&i));     break;
            case 's': avi.firstImg = atoi(getArg(argv,&i));     break;
            default:
                fprintf(stderr,"Unknown option '%c'\n",argv[i][1]);
                usage(argv[0]);
                return 0;
            }
        } else {
            strcpy(avi.szPrefix,argv[i]);
            prefix = 1;
        }
    }
    if(!prefix){
        usage(argv[0]);
        return 0;
    }
    //--------------------------------------------------
    // AVI作成
    //--------------------------------------------------
    create_avifile(&avi);
    return 0;
}
inserted by FC2 system