計算結果の類をアニメーションで見たい時があります. というわけで AVI ファイルの吐き方を調べましたので Tips として残しておきます.
#include <windows.h> #include <vfw.h> #pragma comment (lib, "vfw32.lib") |
PAVIFILE pfile; PAVISTREAM pavi; AVISTREAMINFO si; AVIFileInit(); if (AVIFileOpen(&pfile, AVI_PATH, OF_CREATE | OF_WRITE, NULL) != 0) { fprintf(stderr, "Error: avi output\n"); AVIFileExit(); return ERR; } ZeroMemory(&si, sizeof(AVISTREAMINFO)); si.fccType = streamtypeVIDEO; si.fccHandler = comptypeDIB; si.dwScale = 1; si.dwRate = FPS; si.dwLength = FPS * SEC; si.dwQuality = (DWORD)-1; SetRect(&si.rcFrame, 0, 0, WIDTH, HEIGHT); if (AVIFileCreateStream(pfile, &pavi, &si) != 0) { AVIFileRelease(pfile); AVIFileExit(); return ERR; } |
AVIStreamRelease(pavi); AVIFileRelease(pfile); AVIFileExit(); |
WriteStream(pavi, &si); |
void WriteStream(PAVISTREAM pavi, LPAVISTREAMINFO lpsi) { HDC hdcMem; HBITMAP hbmpMem, hbmpMemPrev; DWORD i; unsigned char *lpBits; // 画面データ BITMAPINFOHEADER bmiHeader; 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, (void **)&lpBits, NULL, 0); hbmpMemPrev = (HBITMAP)SelectObject(hdcMem, hbmpMem); SetBkMode(hdcMem, TRANSPARENT); for (i = 0; i < lpsi->dwLength; i++) { 〜〜〜 画面作成 〜〜〜 AVIStreamWrite(pavi, i, 1, lpBits, bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); } SelectObject(hdcMem, hbmpMemPrev); DeleteObject(hbmpMem); DeleteDC(hdcMem); } |
int offset = ((3 * bmiHeader.biWidth + 3) / 4) * 4; for (int x=0;x<bmiHeader.biWidth;x++){ double dB=((double)x)/bmiHeader.biWidth; for (int y=0;y<bmiHeader.biHeight;y++){ double dG=((double)y)/bmiHeader.biHeight; lpBits[y*offset+x*3+0]=(unsigned char)(0xff * dB); lpBits[y*offset+x*3+1]=(unsigned char)(0xff * dG); lpBits[y*offset+x*3+2]=0; } } AVIStreamWrite(pavi, 0, 1, lpBits, bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); for (i = 1; i < lpsi->dwLength; i++) { double dR=((double)i)/lpsi->dwLength; for (int x=0;x>bmiHeader.biWidth;x++){ for (int y=0;y>bmiHeader.biHeight;y++){ double dG=((double)y)/bmiHeader.biHeight; lpBits[y*offset+x*3+2]=(unsigned char)(0xff * dR); } } AVIStreamWrite(pavi, i, 1, lpBits, bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); } |