English 中文(简体)
Transparency of subtitles in Vista / Windows 7
原标题:

I implemented the EVR renderer into a player of mine to deal with bad resizing quality on Windows Vista+ and came to problems...

I have subtitle overlay problems with the EVR:

try to see what i m talking about - you must set the EVR in options.

I used this to apply a 32bit alpha bitmap onto VMR9, using a DirectX surface:

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

        }

Now however the project MediaFoundation.NET doesnt have the alphaBmp.pDDS pointer to set, so I cannot use a directdraw surface and need to use GDI (IF SOMEONE HAS A METHOD TO DO THIS IT WOULD BE COOL). But with GDI I cannot use 32bit alpha Bitmaps for true transparency - I only get 1 bit transparency with this approach:

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

        }

So the questions are:

  • How to use a DirectDraw surface to mix bitmaps on the EVR video or
  • How to mix a semi transparent bitmap without DirectDraw?

Thank you very much!

问题回答

I ll try to answer the second question...

Alpha blending is rather simple task. Assume that alpha is in the range from 0.0 - 1.0, where 0.0 means fully transparent and 1.0 represents a fully opaque color.

R_result = R_Source * alpha + R_destination * (1.0 - alpha)

Since we don t really need floats here, we can switch alpha to a 0-255 range.

R_result = ( R_Source * alpha + R_destination * (255 - alpha) ) >> 8

You can optimize it further... it s up to you.
Of course, same applies for G and B.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签