• 締切済み

フレーム画像の連続保存について

現在、USBカメラから撮ったフレーム画像を保存するといったプログラムを作成しています。やりたいのはUSBカメラから撮った全てのフレーム画像(例:300フレーム=300枚画像)の保存ですが、今はキーボートを押されるたび画像の保存しかできない状態です。とっても困っています。どうか教えていただけませんか?よろしくお願いします。 while(1){ int v = 0; hr = pGrab -> GetCurrentBuffer( &n, (long *)buffer );// グラブ if( kbhit() ){  getch();//kbhitで取得したキーの破棄  hr = pMC -> Pause(); memset(&bmphdr, 0, sizeof(bmphdr));  bmphdr.bfType = ('M' << 8) | 'B'; bmphdr.bfSize = sizeof(bmphdr) + sizeof(BITMAPINFOHEADER) + n; bmphdr.bfOffBits = sizeof(bmphdr) + sizeof       (BITMAPINFOHEADER);  while(1){ v++; char filename[300];   _snprintf(filename, sizeof(filename),"%d.bmp", v); fh = CreateFile(filename,GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(fh, &bmphdr, sizeof(bmphdr), &nWritten, NULL); WriteFile(fh,&pVideoHeader->bmiHeader, sizeof(BITMAPINFOHEADER), &nWritten, NULL); WriteFile(fh, buffer, n, &nWritten, NULL); CloseHandle(fh); pMC -> Run(); pGrab -> SetBufferSamples(FALSE); if(kbhit()){ break; }  }  printf( "グラブ停止:終了 -- 0 、再開 -- 1 、処理 -- 2\n" );  scanf("%d",&num); }

みんなの回答

回答No.1

 こんばんは。  録画する時はループ中でボタンが押された事を検出したら、開始/停止を見分けて、録画処理にも流れるかどうかを決めると良いかもしれません。実際にはマルチスレッドでするものです。  後、グラブした画像データはBGRになっている様なので、適切な変換が必要の様です。リンクが参考になるでしょう。  http://mist.suenaga.cse.nagoya-u.ac.jp/trac/wiki/Tutorial/Practice2  http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/directshow.html  私はUSBカメラを所有していないので、printfで流れを確認した程度ですが、以下参考程度に。 //グラブしたビデオ画像データ typedef struct _VideoData { void* pBuffer; long lSize; } VIDEODATA, *LPVIDEODATA; //ファイルヘッダを初期化 static void InitFileHeader(LPBITMAPFILEHEADER pFileHeader, DWORD dwBufferSize) { pFileHeader->bfType = ('M' << 8) | 'B'; pFileHeader->bfOffBits = sizeof(*pFileHeader) + sizeof(BITMAPINFOHEADER); pFileHeader->bfSize = pFileHeader->bfOffBits + dwBufferSize; } //グラブしたビデオ画像データをセーブする static void SaveFrame(HANDLE hFile, const LPBITMAPFILEHEADER pFileHeader, const LPBITMAPINFO pVideoHeader, const LPVIDEODATA pVideoData) { DWORD nWritten = 0; ::WriteFile(hFile, pFileHeader, sizeof(*pFileHeader), &nWritten, NULL); ::WriteFile(hFile, &pVideoHeader->bmiHeader, sizeof(BITMAPINFOHEADER), &nWritten, NULL); ::WriteFile(hFile, pVideoData->pBuffer, pVideoData->lSize, &nWritten, NULL); } //グラブしてビデオ画像データを作成する static HRESULT GrabVideoData(ISampleGrabber* pGrab, LPVIDEODATA pVideoData/*out*/) { do//もしかしたら、このループは要らないかもしれない { pGrab->GetCurrentBuffer(&pVideoData->lSize, NULL); }while(pVideoData->lSize <= 0); pVideoData->pBuffer = ::malloc(pVideoData->lSize); return pGrab->GetCurrentBuffer(&pVideoData->lSize, static_cast<long*>(pVideoData->pBuffer)); } //ビデオ画像データを始末する static void ReleaseVideoData(LPVIDEODATA pVideoData) { ::free(pVideoData->pBuffer); pVideoData->pBuffer = 0; pVideoData->lSize = 0; } //メイン int main(void) { //HRESULT hr = 0; //ISampleGrabber* pGrab = 0; //IMediaControl* pMC = 0; //BITMAPFILEHEADER bmphdr; //LPBITMAPINFO pVideoHeader; VIDEODATA videoData = {0};//ビデオ画像データ int v = 0;//ファイルの連番 HANDLE fh = NULL;//ファイルハンドル char filename[MAX_PATH + 1] = {0}; filename[MAX_PATH] = '\0'; BOOL bCapture = FALSE;//ココをTRUEにすると録画状態から始まる ::printf("[初期状態 : %s]\n", bCapture ? "開始" : "停止"); while(1) { //16ミリ秒停止する ::Sleep(16); //キーボード入力 if(::kbhit()) { const int key = ::getch(); if(key == '0') { //トグルする ::printf("%s\n", (bCapture ^= TRUE) ? "グラブ開始" : "グラブ停止"); //サンプルの設定 pGrab->SetBufferSamples(bCapture); } else if(key == '1') { //終了する ::printf("%s\n", "終了"); //サンプルの設定(此れは無くても良いと思う) pGrab->SetBufferSamples(FALSE); break; } } //撮影中ではないので引き返す if(bCapture == FALSE) continue; //グラブしてビデオバッファを作成 hr = ::GrabVideoData(pGrab, &videoData); //ファイルヘッダの初期化 ::InitFileHeader(&bmphdr, videoData.lSize); //ポーズ hr = pMC->Pause(); //フレームのセーブ ::_snprintf(filename, sizeof(filename),"%d.bmp", ++v); ::printf("[フレーム : %d][filename : %s]\n", v, filename); fh = ::CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ::SaveFrame(fh, &bmphdr, pVideoHeader, &videoData); ::CloseHandle(fh); //再開 pMC->Run(); //ビデオバッファを始末 ::ReleaseVideoData(&videoData); } return 0; }

goofy119
質問者

お礼

ご丁寧に答えていただいてありがとうございます。 とっても参考になり、助かります。 また、参考URLも見させていただいたので、勉強に なりました。 どうもありがとうございました。

関連するQ&A