0

我尝试使用此代码来获取我的摄像头的照片:

            IGraphBuilder _graph = null;
            ISampleGrabber _grabber = null;
            IBaseFilter _sourceObject = null;
            IBaseFilter _grabberObject = null;
            IMediaControl _control = null;

            // Create the main graph
            _graph = Activator.CreateInstance(Type.GetTypeFromCLSID(FilterGraph)) as IGraphBuilder;

            // Create the webcam source
            _sourceObject = FilterInfo.CreateFilter(_monikerString);

            // Create the grabber
            _grabber = Activator.CreateInstance(Type.GetTypeFromCLSID(SampleGrabber)) as ISampleGrabber;
            _grabberObject = _grabber as IBaseFilter;

            // Add the source and grabber to the main graph
            _graph.AddFilter(_sourceObject, "source");
            _graph.AddFilter(_grabberObject, "grabber");

            IPin pin = _sourceObject.GetPin(PinDirection.Output, 0);

            IAMStreamConfig streamConfig = pin as IAMStreamConfig;
            int count = 0, size = 0;
            streamConfig.GetNumberOfCapabilities(out count, out size);

            int width = 0, height = 0;
            AMMediaType mediaType = null;
            AMMediaType mediaTypeCandidate = null;
            for(int index = 0; index < count; index++) {
                VideoStreamConfigCaps scc = new VideoStreamConfigCaps();
                int test = streamConfig.GetStreamCaps(index, out mediaTypeCandidate, scc);
                if(mediaTypeCandidate.MajorType == MediaTypes.Video && mediaTypeCandidate.SubType == MediaSubTypes.YUY2) {
                    VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaTypeCandidate.FormatPtr, typeof(VideoInfoHeader));

                    if(header.BmiHeader.Width == 1280 && header.BmiHeader.Height == 720) {
                        width = header.BmiHeader.Width;
                        height = header.BmiHeader.Height;
                        if(mediaType != null)
                            mediaType.Dispose();
                        mediaType = mediaTypeCandidate;
                    } else
                        mediaTypeCandidate.Dispose();
                } else
                    mediaTypeCandidate.Dispose();
            }

            streamConfig.SetFormat(mediaType);

它可以工作,但我看不到此代码生成的图像:

uint pcount = (uint)(_capGrabber.Width * _capGrabber.Height * PixelFormats.Bgr32.BitsPerPixel / 8);

                    // Create a file mapping
                    _section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04, 0, pcount, null);
                    _map = MapViewOfFile(_section, 0xF001F, 0, 0, pcount);

                    // Get the bitmap
                    BitmapSource = Imaging.CreateBitmapSourceFromMemorySection(_section, _capGrabber.Width,
                        _capGrabber.Height, PixelFormats.Bgr32, _capGrabber.Width * PixelFormats.Bgr32.BitsPerPixel / 8, 0) as InteropBitmap;
                    _capGrabber.Map = _map;

                    // Invoke event
                    if (NewBitmapReady != null)
                    {
                        NewBitmapReady(this, null);
                    }

因为 SubMediaTyp 是 YUY2。如何在此代码中添加转换器?我已经阅读了一些关于 ColorConvert 的内容,可以将其添加到 IGraphBuilder 中。这是如何运作的?

4

1 回答 1

0

除了RGB 的味道,我不希望CreateBitmapSourceFromMemorySection接受其他任何东西。它更不可能接受媒体类型,因此您需要 DirectShow 管道将视频流转换为 RGB,然后再将其导出为托管位图/图像对象。YUY2

为此,您通常添加初始化为 24 位 RGB 子类型的 Sample Grabber 过滤器,并让 DirectShow 自动提供必要的转换器。

请在此处查看详细说明和代码片段:DirectShow:使用 SampleGrabber 抓取框架和...的示例

media.majorType    = MediaType.Video;
media.subType    = MediaSubType.RGB24;
media.formatPtr = IntPtr.Zero;
hr = sampGrabber.SetMediaType(media);
于 2012-07-26T18:22:17.957 回答