簡易アニメをAVI出力するコード C++ でAVI出力

 C++で作成する簡易アニメをAVI出力するコードです。G++でビルドできます。WindowsのAPIを使っているのでWindows専用だと考えます。既にGDIで出力できるスキルが有れば簡単にAVI形式でアニメ(動画)を出力できます。実験結果を簡易的にCGにするなどの目的に使えそうです。 以下のコードをUTF-8で保存してコンパイルしてください。サンプルコードでは320x240ですが、ストレステストとしてFullHD(1920x1080)や4Kでの出力もテストしています。8Kも出力しましたが再生環境が無いので出力確認は出来ていません。




  1. #define _UNICODE    //ワイド文字列 (Unicode) 対応
  2. #include <windows.h>
  3. #include <vfw.h>
  4. #include <sstream>
  5. #include <string>
  6. /********************************************************************
  7. 実行すると100までカウントアップするAVI動画を作成します。以下のコマンドラインでビルドしてください。
  8. g++ .\avisample001.cpp -mwindows -lvfw32 -municode -o avisample001
  9. *********************************************************************/
  10. int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hinstPrev, LPWSTR lpszCmdLine, int nCmdShow)
  11. {
  12.     const int width = 320; //画面サイズフレームレートなどを設定
  13.     const int height = 240;
  14.     const int fps = 2;
  15.     
  16.     PAVIFILE pfile;
  17.     PAVISTREAM pavi;
  18.     AVISTREAMINFO si;
  19.     LPAVISTREAMINFO lpsi = &si;
  20.     LPVOID lpBits;
  21.     BITMAPINFOHEADER bmiHeader;    
  22.     
  23.     AVIFileInit();
  24.     if (AVIFileOpen(&pfile, L"video.avi", OF_CREATE | OF_WRITE, NULL) != 0) {
  25.         MessageBox(NULL, L"Fail file open.", L"OK", MB_OK);
  26.         AVIFileExit();
  27.         return 0;}
  28.     ZeroMemory(&si, sizeof(AVISTREAMINFO));
  29.     si.fccType = streamtypeVIDEO;
  30.     si.fccHandler = comptypeDIB;
  31.     si.dwScale = 1;
  32.     si.dwRate = fps;
  33.     si.dwLength = 0;
  34.     si.dwQuality = (DWORD)-1;
  35.     SetRect(&si.rcFrame, 0, 0, width, height);
  36.     if (AVIFileCreateStream(pfile, &pavi, &si) != 0) {
  37.         MessageBox(NULL, TEXT("Fail open stream."), TEXT("OK"), MB_OK);
  38.         AVIFileRelease(pfile);
  39.         AVIFileExit();
  40.         return 0;}
  41.     ZeroMemory(&bmiHeader, sizeof(BITMAPINFOHEADER));
  42.     bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  43.     bmiHeader.biWidth = lpsi->rcFrame.right;
  44.     bmiHeader.biHeight = lpsi->rcFrame.bottom;
  45.     bmiHeader.biPlanes = 1;
  46.     bmiHeader.biBitCount = 24;
  47.     bmiHeader.biCompression = BI_RGB;
  48.     bmiHeader.biSizeImage = bmiHeader.biHeight * ((3 * bmiHeader.biWidth + 3) / 4) * 4;
  49.     AVIStreamSetFormat(pavi, 0, &bmiHeader, sizeof(BITMAPINFOHEADER));
  50.     //ここにHDCへ描画し、AVIStreamWriteを呼び出し一コマ書き出す。これを繰り返す。
  51.     HDC hdc = CreateCompatibleDC(NULL);
  52.     HBITMAP hbmpMem = CreateDIBSection(NULL, (LPBITMAPINFO)&bmiHeader, DIB_RGB_COLORS, &lpBits, NULL, 0);
  53.     HBITMAP hbmpMemPrev = (HBITMAP)SelectObject(hdc, hbmpMem);
  54.     
  55.     SetTextColor(hdc, RGB(255, 255, 255));
  56.     HGDIOBJ hFont = CreateFontW(100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
  57.         CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"UI Gothic");
  58.     HGDIOBJ hFontOld = SelectObject(hdc, hFont);
  59.     
  60.     HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
  61.     HBRUSH hPrevBrush =(HBRUSH)SelectObject(hdc,hBrush);
  62.     
  63.     SetBkMode(hdc, TRANSPARENT);
  64.     for (int fCnt = 0; fCnt < 100; fCnt++) {
  65.         FillRect(hdc, &lpsi->rcFrame, (HBRUSH)GetStockObject(BLACK_BRUSH)); //背景を黒で塗る
  66.         
  67.         std::wstringstream wss;
  68.         wss << fCnt;
  69.         std::wstring buf = wss.str();
  70.         const int c_width = 30;
  71.         const int div = 8;
  72.         const int step = 360 / div;
  73.         const int seg = step / 2;
  74.         BeginPath(hdc);
  75.         AngleArc(hdc,width/2,height/2,height/2-20,0,0);
  76.         EndPath(hdc);        
  77.         
  78.         for (int j = 0;j<fCnt%(div+1);j++){ //区切りの数+1がアニメのコマ数になる
  79.             BeginPath(hdc);
  80.             AngleArc(hdc,width/2,height/2,height/2-20,step*j,0);
  81.             EndPath(hdc);    
  82.             BeginPath(hdc);
  83.             AngleArc(hdc,width/2,height/2,height/2-20,step*j,seg);
  84.             AngleArc(hdc,width/2,height/2,height/2-20-c_width,step*j+seg,-seg);
  85.             CloseFigure(hdc);
  86.             EndPath(hdc);    
  87.             FillPath(hdc);
  88.         }
  89.         
  90.         DrawText(hdc, buf.c_str(), -1, &lpsi->rcFrame, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  91.         AVIStreamWrite(pavi, fCnt, 1, lpBits, bmiHeader.biSizeImage, AVIIF_KEYFRAME, NULL, NULL); //一コマ書き出し
  92.     }
  93.     
  94.     
  95.     SelectObject(hdc,hPrevBrush);
  96.     DeleteObject(hBrush);
  97.     SelectObject(hdc, hFontOld);
  98.     DeleteObject(hFont);
  99.     SelectObject(hdc, hbmpMemPrev);
  100.     DeleteObject(hbmpMem);
  101.     DeleteDC(hdc);
  102.     AVIStreamRelease(pavi);
  103.     AVIFileRelease(pfile);
  104.     AVIFileExit();
  105.     MessageBox(NULL, L"Done.", L"OK", MB_OK);
  106.     return 0;
  107. }


劇遅 メモリ交換だけで古いセレロンパソコンを使えるレベルにアップグレード esprimo FH52/W 2950M SP016GLSTU160N22

Amazonでメモリを購入します ウチにある古いパソコンの富士通ESPRIMO FH52/W が酷く遅くなりました。OSの起動も遅く、アプリの起動も遅いです。さらにブラウザや事務ソフト程度の軽いソフトも突然固まります。30秒くらい待っていればまた使えるようになりますがストレスはあ...