Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Vista/Windows 7中字幕的透明度_C#_C++_Directshow_Ms Media Foundation - Fatal编程技术网

C# Vista/Windows 7中字幕的透明度

C# Vista/Windows 7中字幕的透明度,c#,c++,directshow,ms-media-foundation,C#,C++,Directshow,Ms Media Foundation,我在我的一个播放器中实现了EVR渲染器,以处理Windows Vista+上的不良大小调整质量,并遇到了一些问题 我的EVR有字幕覆盖问题: -必须在选项中设置EVR 我使用DirectX曲面将32位alpha位图应用于VMR9: private void SetVRM9MixerSettings(int width, int height, int lines) { int hr = 0; VMR9AlphaBitmap alph

我在我的一个播放器中实现了EVR渲染器,以处理Windows Vista+上的不良大小调整质量,并遇到了一些问题

我的EVR有字幕覆盖问题:

-必须在选项中设置EVR

我使用DirectX曲面将32位alpha位图应用于VMR9:

private void SetVRM9MixerSettings(int width, int height, int lines)
        {
            int hr = 0;
            VMR9AlphaBitmap alphaBmp;               

            // Set Alpha Bitmap Parameters for using a Direct3D surface
            alphaBmp = new VMR9AlphaBitmap();
            alphaBmp.dwFlags = VMR9AlphaBitmapFlags.EntireDDS | VMR9AlphaBitmapFlags.FilterMode;

            // on unmanagedSurface the bitmap was drawn with transparency
            alphaBmp.pDDS = unmanagedSurface;
            alphaBmp.rDest = GetDestRectangle(width, height, lines);
            alphaBmp.fAlpha = 1.0f;
            alphaBmp.dwFilterMode = VMRMixerPrefs.BiLinearFiltering;

            // for anaglyph half SBS
            if (FrameMode == Mars.FrameMode.HalfSideBySide)
            {
                alphaBmp.rDest.left /= 2;
                alphaBmp.rDest.right /= 2;
            }

            // Set Alpha Bitmap Parameters
            hr = mixerBitmap.SetAlphaBitmap(ref alphaBmp);
            DsError.ThrowExceptionForHR(hr);

        }
然而,现在项目MediaFoundation.NET没有要设置的alphaBmp.pDDS指针,因此我不能使用directdraw曲面,需要使用GDI(如果有人有这样做的方法,那就太酷了)。但在GDI中,我无法使用32位alpha位图来实现真正的透明度-通过这种方法,我只能获得1位透明度:

 private void SetEVRMixerSettings(int width, int height, int subtitleLines)
        {
            MFVideoAlphaBitmap alphaBmp = new MFVideoAlphaBitmap();

            //alphaBitmap is a 32bit semitransparent Bitmap
            Graphics g = Graphics.FromImage(alphaBitmap);

            // get pointer to needed objects
            IntPtr hdc = g.GetHdc();
            IntPtr memDC = CreateCompatibleDC(hdc);
            IntPtr hBitmap = alphaBitmap.GetHbitmap();
            IntPtr hOld = SelectObject(memDC, hBitmap);

            alphaBmp.GetBitmapFromDC = true;
            alphaBmp.stru = memDC;
            alphaBmp.paras = new MFVideoAlphaBitmapParams();
            alphaBmp.paras.dwFlags = MFVideoAlphaBitmapFlags.Alpha | MFVideoAlphaBitmapFlags.SrcColorKey | MFVideoAlphaBitmapFlags.DestRect;

            // calculate destination rectangle
            MFVideoNormalizedRect mfNRect = new MFVideoNormalizedRect();
            NormalizedRect nRect = GetDestRectangle(width, height, subtitleLines);

            mfNRect.top = nRect.top;
            mfNRect.left = nRect.left;
            mfNRect.right = nRect.right;
            mfNRect.bottom = nRect.bottom;

            // used when viewing half side by side anaglyph video that is stretched to full width
            if (FrameMode == Mars.FrameMode.HalfSideBySide)
            {
                mfNRect.left /= 2;
                mfNRect.right /= 2;
            } 

            alphaBmp.paras.nrcDest = mfNRect;

            // calculate source rectangle (full subtitle bitmap)
            MFRect rcSrc = new MFRect();
            rcSrc.bottom = alphaBitmap.Height;
            rcSrc.right = alphaBitmap.Width;
            rcSrc.top = 0;
            rcSrc.left = 0;

            alphaBmp.paras.rcSrc = rcSrc;

            // apply 1-bit transparency 
            System.Drawing.Color colorKey = System.Drawing.Color.Black;
            alphaBmp.paras.clrSrcKey = ColorTranslator.ToWin32(colorKey);

            // 90% visible
            alphaBmp.paras.fAlpha = 0.9F;

            // set the bitmap to the evr mixer
            evrMixerBitmap.SetAlphaBitmap(alphaBmp);

            // cleanup
            SelectObject(memDC, hOld);
            DeleteDC(memDC);
            g.ReleaseHdc();

        }
因此,问题是:

  • 如何使用DirectDraw曲面在EVR视频上混合位图 或
  • 如何在没有DirectDraw的情况下混合半透明位图

多谢各位

我将尝试回答第二个问题

Alpha混合是一项相当简单的任务。 假设alpha在0.0到1.0之间,其中0.0表示完全透明,1.0表示完全不透明的颜色

R_result = R_Source * alpha + R_destination * (1.0 - alpha)
因为这里不需要浮动,所以我们可以将alpha切换到0-255范围

R_result = ( R_Source * alpha + R_destination * (255 - alpha) ) >> 8
你可以进一步优化它。。。这取决于你。

当然,这同样适用于G和B。

感谢natko的努力,但不幸的是,这需要在CPU上本地获取帧数据,并在CPU上进行alpha混合,对于全高清视频,这实际上会吃掉CPU。第二个片段的结果是将位图发送到EVR混合器,并将位图混合到GPU上的视频帧上。由于您将仅混合字幕区域,因此CPU负载不会明显增加。这甚至适用于旧的、速度慢的单核CPU。无论如何,RGB颜色空间是一个糟糕的选择。在全帧操作中,通过使用一些YUV颜色格式,可以大大减少CPU负载。16位格式甚至12位平面格式中的一些是此类用途的某种标准,而图片质量保持不变。