在Vista / Windows 7字幕的透明度

Transparency of subtitles in Vista / Windows 7

本文关键字:字幕 透明度 Windows Vista      更新时间:2023-10-16

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

我有字幕覆盖问题与EVR:

试着看看我在说什么-你必须在选项中设置EVR。

我用它在VMR9上应用了一个32位的alpha位图,使用DirectX表面:

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);
        }

现在项目medifoundation。. NET没有alphaBmp。pdd指针设置,所以我不能使用直接绘制表面,需要使用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也一样。