C++でAVIファイルを作成するサンプルコード

 C++でAVIの動画ファイルを出力する方法です。以下のソースコードをG++でビルドすることで0から100までのカウントアップ動画を出力します。GDIに描画する方法を知っていればその内容をアニメーションにして出力できます。また、CSVのデータを読み込み動画に合わせて出力する(サイコンからのデータを動画にする)などの応用が可能です。

出力サンプル


ソースコード

  1. #include <windows.h>
  2. #include <vfw.h>
  3. #pragma comment (lib, "vfw32.lib")
  4. //実行すると100までカウントアップするAVI動画を作成します。以下のコンパイルオプションでビルドしてください。
  5. //g++ .\outCntAvi.cpp -mwindows -lvfw32
  6. int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
  7. {
  8.     PAVIFILE pfile;
  9.     PAVISTREAM pavi;
  10.     AVISTREAMINFO si;
  11.     LPAVISTREAMINFO lpsi = &si;
  12.     HDC hdcMem;
  13.     HBITMAP hbmpMem, hbmpMemPrev;
  14.     DWORD i;
  15.     TCHAR szBuf[32];
  16.     LPVOID lpBits;
  17.     BITMAPINFOHEADER bmiHeader;    
  18.     
  19.     AVIFileInit();
  20.     if (AVIFileOpen(&pfile, TEXT("video.avi"), OF_CREATE | OF_WRITE, NULL) != 0) {
  21.         MessageBox(NULL, TEXT("Fail file open."), TEXT("OK"), MB_OK);
  22.         AVIFileExit();
  23.         return 0;
  24.     }
  25.     ZeroMemory(&si, sizeof(AVISTREAMINFO));
  26.     si.fccType = streamtypeVIDEO;
  27.     si.fccHandler = comptypeDIB;
  28.     si.dwScale = 1;
  29.     si.dwRate = 2;
  30.     si.dwLength = 0;
  31.     si.dwQuality = (DWORD)-1;
  32.     SetRect(&si.rcFrame, 0, 0, 320, 240);
  33.     if (AVIFileCreateStream(pfile, &pavi, &si) != 0) {
  34.         MessageBox(NULL, TEXT("Fail open stream."), TEXT("OK"), MB_OK);
  35.         AVIFileRelease(pfile);
  36.         AVIFileExit();
  37.         return 0;
  38.     }
  39.     ZeroMemory(&bmiHeader, sizeof(BITMAPINFOHEADER));
  40.     bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  41.     bmiHeader.biWidth = lpsi->rcFrame.right;
  42.     bmiHeader.biHeight = lpsi->rcFrame.bottom;
  43.     bmiHeader.biPlanes = 1;
  44.     bmiHeader.biBitCount = 24;
  45.     bmiHeader.biCompression = BI_RGB;
  46.     bmiHeader.biSizeImage = bmiHeader.biHeight * ((3 * bmiHeader.biWidth + 3) / 4) * 4;
  47.     AVIStreamSetFormat(pavi, 0, &bmiHeader, sizeof(BITMAPINFOHEADER));
  48.     hdcMem = CreateCompatibleDC(NULL);
  49.     hbmpMem = CreateDIBSection(NULL, (LPBITMAPINFO)&bmiHeader, DIB_RGB_COLORS, &lpBits, NULL, 0);
  50.     hbmpMemPrev = (HBITMAP)SelectObject(hdcMem, hbmpMem);
  51.     SetBkMode(hdcMem, TRANSPARENT);
  52.     SetTextColor(hdcMem, RGB(255, 255, 255));
  53.     HGDIOBJ hFont = CreateFontW(100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
  54.         CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"UI Gothic");
  55.     HGDIOBJ hFontOld = SelectObject(hdcMem, hFont);    
  56.     for (int fCnt = 0; fCnt < 100; fCnt++) {
  57.         wsprintf(szBuf, TEXT("%d"), fCnt);
  58.         FillRect(hdcMem, &lpsi->rcFrame, (HBRUSH)GetStockObject(BLACK_BRUSH));
  59.         DrawText(hdcMem, szBuf, -1, &lpsi->rcFrame, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  60.         AVIStreamWrite(pavi, fCnt, 1, lpBits, bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
  61.     }
  62.     
  63.     SelectObject(hdcMem, hFontOld);
  64.     DeleteObject(hFont);
  65.     
  66.     SelectObject(hdcMem, hbmpMemPrev);
  67.     DeleteObject(hbmpMem);
  68.     DeleteDC(hdcMem);
  69.     
  70.     MessageBox(NULL, TEXT("Done."), TEXT("OK"), MB_OK);
  71.     AVIStreamRelease(pavi);
  72.     AVIFileRelease(pfile);
  73.     AVIFileExit();
  74.     return 0;
  75. }

簡単に手持ちのC,C++の処理に進捗バーを実装する方法

 C言語やC++で何か処理を書ける人は多いですが、Windowプログラムとなると実装方法が難しいです。VisualStudioのプロジェクトの雛形にボタンを配置し、そこから手持ちのコードを起動すれば動きそうです。 しかし、その方法では「未応答」状態になったり、ウィンドウの操作すら...