あなたの助けのおかげで、directshowをもう少しうまく使うための正しい単語を検索することができました。SampleGrabberオブジェクトの使用方法のチュートリアルをここで見つけました:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd407288%28v=vs.85%29.aspx
最初のフレームだけでなく、すべてのフレームをPNGに保存するように、実装して少し変更することができます。そのために私はコロナを使います。しかし、私は周りの何かを推測しただけで、どのバッファに私のデータが含まれていて、どの形式であるのかよくわかりません。
それで、私は基本的に3つの質問があります:
私はSavePNGを正しく使用していますか?結果の画像は逆さまになります!
ビデオのBaseFilterをカメラに接続されているものと交換できますか?
pBuffer [123]と入力するだけでrgb-byte-informationを取得できるように、ImagedataにpBufferが含まれていますか?
私はembarcaderoのC++-Builder(XE2 16)を使用しています。
これが私がウェブサイトで見つけたコードですが、少し変更されています(見やすくするためにエラー処理が削除されています。各時間の後に= ...失敗したチェックがあります):
void __fastcall TForm1::btn_kameraClick(TObject *Sender)
{
HRESULT hr = S_OK;
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEventEx *pEvent = NULL;
IBaseFilter *pGrabberF = NULL;
ISampleGrabber *pGrabber = NULL;
IBaseFilter *pSourceF = NULL;
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IBaseFilter *pNullF = NULL;
BYTE *pBuffer = NULL;
hr = CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pGraph));
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pEvent));
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pGrabberF));
hr = pGraph->AddFilter(pGrabberF, L"Sample Grabber");
hr = pGrabberF->QueryInterface(IID_PPV_ARGS(&pGrabber));
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(mt));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);
hr = pGraph->AddSourceFilter(L"C:/Users/Julian/Desktop/homogenität/1,1x_2,7y.mpg", L"Source", &pSourceF);
hr = pSourceF->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = ConnectFilters(pGraph, pPin, pGrabberF);
SafeRelease(&pPin);
if (SUCCEEDED(hr))break;
}
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pNullF));
hr = pGraph->AddFilter(pNullF, L"Null Filter");
hr = ConnectFilters(pGraph, pGrabberF, pNullF);
hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);
long evCode=0;
long cbBuffer=0;
hr = pControl->Run();
hr = pEvent->WaitForCompletion(INFINITE, &evCode);
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
pBuffer = (BYTE*)CoTaskMemAlloc(cbBuffer);
hr = pGrabber->GetConnectedMediaType(&mt);
CComQIPtr< IMediaSeeking, &IID_IMediaSeeking > pSeeking( pGraph );
// for(int i=0;i<10;i++){
bool hui=true;int i=0;
while(hui){
REFERENCE_TIME Start = i * UNITS;
hr = pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning,NULL, AM_SEEKING_NoPositioning );
// Sleep(10);
hr = pEvent->WaitForCompletion(INFINITE,&evCode);
if(hr!=0)hui=false;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
if ((mt.formattype == FORMAT_VideoInfo) &&(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&(mt.pbFormat != NULL))
{
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)mt.pbFormat;
// hr = WriteBitmap(("hui"+(String)i+".bmp").c_str(), &pVih->bmiHeader, mt.cbFormat - SIZE_PREHEADER, pBuffer, cbBuffer);
hr = SavePNG(i,pBuffer, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight);
}
else hr = VFW_E_INVALIDMEDIATYPE;
i++;
}
FreeMediaType(mt);
done:
CoTaskMemFree(pBuffer);
SafeRelease(&pPin);
SafeRelease(&pEnum);
SafeRelease(&pNullF);
SafeRelease(&pSourceF);
SafeRelease(&pGrabber);
SafeRelease(&pGrabberF);
SafeRelease(&pControl);
SafeRelease(&pEvent);
SafeRelease(&pGraph);
}
bool SavePNG(int i, Byte* m_pImageData,long m_Width,long m_Height)
{
// Make sure there is image data
if (!m_pImageData)
return false;
stringstream FilePath;
FilePath << "hui"<< i<<".png";
// Create a corona image
corona::Image* pImage = corona::CreateImage(m_Width, m_Height, corona::PF_R8G8B8, m_pImageData);
// Make sure the image was created
if (!pImage)
return false;
// Save the image to a PNG file
corona::SaveImage(FilePath.str().c_str(), corona::FF_PNG, pImage);
// Delete the corona image
delete pImage;
// Nothing went wrong
return true;
}
私はひどく悪いことを何もしていないことを願っています...私は本当にすべてを研究しようとしました^^誰かが上記の私の3つの質問について知っていますか?ここで本当に間違っていることがわかりました。また、修正して改善できるように、教えていただければ幸いです。
よろしく、ジュリアン