C++でAVIの動画ファイルを出力する方法です。以下のソースコードをG++でビルドすることで0から100までのカウントアップ動画を出力します。GDIに描画する方法を知っていればその内容をアニメーションにして出力できます。また、CSVのデータを読み込み動画に合わせて出力する(サイコンからのデータを動画にする)などの応用が可能です。
出力サンプル
ソースコード
- #include <windows.h>
- #include <vfw.h>
- #pragma comment (lib, "vfw32.lib")
- //実行すると100までカウントアップするAVI動画を作成します。以下のコンパイルオプションでビルドしてください。
- //g++ .\outCntAvi.cpp -mwindows -lvfw32
- int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
- {
- PAVIFILE pfile;
- PAVISTREAM pavi;
- AVISTREAMINFO si;
- LPAVISTREAMINFO lpsi = &si;
- HDC hdcMem;
- HBITMAP hbmpMem, hbmpMemPrev;
- DWORD i;
- TCHAR szBuf[32];
- LPVOID lpBits;
- BITMAPINFOHEADER bmiHeader;
-
- AVIFileInit();
- if (AVIFileOpen(&pfile, TEXT("video.avi"), OF_CREATE | OF_WRITE, NULL) != 0) {
- MessageBox(NULL, TEXT("Fail file open."), TEXT("OK"), MB_OK);
- AVIFileExit();
- return 0;
- }
- ZeroMemory(&si, sizeof(AVISTREAMINFO));
- si.fccType = streamtypeVIDEO;
- si.fccHandler = comptypeDIB;
- si.dwScale = 1;
- si.dwRate = 2;
- si.dwLength = 0;
- si.dwQuality = (DWORD)-1;
- SetRect(&si.rcFrame, 0, 0, 320, 240);
- if (AVIFileCreateStream(pfile, &pavi, &si) != 0) {
- MessageBox(NULL, TEXT("Fail open stream."), TEXT("OK"), MB_OK);
- AVIFileRelease(pfile);
- AVIFileExit();
- return 0;
- }
- ZeroMemory(&bmiHeader, sizeof(BITMAPINFOHEADER));
- bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmiHeader.biWidth = lpsi->rcFrame.right;
- bmiHeader.biHeight = lpsi->rcFrame.bottom;
- bmiHeader.biPlanes = 1;
- bmiHeader.biBitCount = 24;
- bmiHeader.biCompression = BI_RGB;
- bmiHeader.biSizeImage = bmiHeader.biHeight * ((3 * bmiHeader.biWidth + 3) / 4) * 4;
- AVIStreamSetFormat(pavi, 0, &bmiHeader, sizeof(BITMAPINFOHEADER));
- hdcMem = CreateCompatibleDC(NULL);
- hbmpMem = CreateDIBSection(NULL, (LPBITMAPINFO)&bmiHeader, DIB_RGB_COLORS, &lpBits, NULL, 0);
- hbmpMemPrev = (HBITMAP)SelectObject(hdcMem, hbmpMem);
- SetBkMode(hdcMem, TRANSPARENT);
- SetTextColor(hdcMem, RGB(255, 255, 255));
- HGDIOBJ hFont = CreateFontW(100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
- CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"UI Gothic");
- HGDIOBJ hFontOld = SelectObject(hdcMem, hFont);
- for (int fCnt = 0; fCnt < 100; fCnt++) {
- wsprintf(szBuf, TEXT("%d"), fCnt);
- FillRect(hdcMem, &lpsi->rcFrame, (HBRUSH)GetStockObject(BLACK_BRUSH));
- DrawText(hdcMem, szBuf, -1, &lpsi->rcFrame, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- AVIStreamWrite(pavi, fCnt, 1, lpBits, bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
- }
-
- SelectObject(hdcMem, hFontOld);
- DeleteObject(hFont);
-
- SelectObject(hdcMem, hbmpMemPrev);
- DeleteObject(hbmpMem);
- DeleteDC(hdcMem);
-
- MessageBox(NULL, TEXT("Done."), TEXT("OK"), MB_OK);
- AVIStreamRelease(pavi);
- AVIFileRelease(pfile);
- AVIFileExit();
- return 0;
- }