プログラムの一部として、ユーザーが指定したビデオ ファイルからいくつかのランダムなフレームを取得できる必要があります。私はビデオ処理プログラミングの経験がないので、これは初めてのことです。
Windows XP で .Net を使用してこれを行うには、DirectShow.net を使用する必要があると判断しましたが、その方法がわかりません。ISampleGrabber インターフェイスを使用しようとしていますが、すべてを理解することはできず、例も見つかりません。
インターネット上で DirectShow.net を使用した例はほとんどありませんが、誰かが .net を使用してビデオからフレームを取り出したことは確かです。そのため、これを実行するサンプル コードまたはそれに近いものを誰かが知っているかどうかを確認したいと思います。
このコード プロジェクトの記事に従って、次のコードを思いつきました。
// step 1
IGraphBuilder graphBuilder = (IGraphBuilder)new FilterGraph();
// step 2
IBaseFilter grabberBaseFilter;
ISampleGrabber sampleGrabber;
AMMediaType mt;
grabberBaseFilter = (IBaseFilter)new SampleGrabber();
sampleGrabber = (ISampleGrabber)grabberBaseFilter;
graphBuilder.AddFilter(grabberBaseFilter, "Grabber");
// step 3
mt = new AMMediaType();
mt.majorType = MediaType.Video;
mt.subType = MediaSubType.RGB24;
mt.formatType = FormatType.VideoInfo;
sampleGrabber.SetMediaType(mt);
graphBuilder.RenderFile(filename, null);
IMediaControl mediaControl = (IMediaControl)graphBuilder;
IMediaEvent mediaEventEx = (IMediaEvent)graphBuilder;
sampleGrabber.SetBufferSamples(true);
sampleGrabber.SetOneShot(true);
// step 4
mediaControl.Run();
EventCode evCode;
mediaEventEx.WaitForCompletion(int.MaxValue, out evCode);
AMMediaType connectedMediaType = new AMMediaType();
sampleGrabber.GetConnectedMediaType(connectedMediaType);
VideoInfoHeader videoHeader = (VideoInfoHeader)connectedMediaType.formatType;
BitmapInfo bitmapInfo = new BitmapInfo();
bitmapInfo.bmiHeader = videoHeader.BmiHeader;
// ::CreateDIBSection(0, &BitmapInfo, DIB_RGB_COLORS, &buffer, NULL, 0);
// legacy - GdiFlush();
// Copy the image into the buffer.
int size = 0;
sampleGrabber.GetCurrentBuffer(ref size, buffer);
コンパイルされない部分は、バッファ変数がないため、videoHeader キャスト行と最後の GetCurrentBuffer 行です...しかし、それを修正するために何をすべきかわかりません。