0

あなたの助けのおかげで、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つの質問について知っていますか?ここで本当に間違っていることがわかりました。また、修正して改善できるように、教えていただければ幸いです。

よろしく、ジュリアン

4

1 に答える 1

0

これで、24ビットRGB形式のビデオフレームがある場合、必要なのはPNGに圧縮することだけです。ここで選択肢があります:

おそらく、C++バルダーにはカバーするネイティブクラスPNGもあります。

使用しているPSDirectShowAPIはDirectXではなく、WindowsコアSDKの一部です。

于 2012-08-18T14:16:10.967 に答える