none
WPF + XAML Islands/MediaPlayerElement/WebView hwnd/handle/surface into wpf friendly bitmap RRS feed

  • Question

  • Hi there,

    Anyone know if MediaPlayerElement and WebView controls expose a hwnd/handle/surface that I can access to generate a WPF friendly bitmap from?

    I've had a hunt around manuals/documentation/structures/etc. but can't seem to find anything :/

    From my experiments so far, these things run under their own separate handles, outside of the parent WPF window, and I want to get at their graphical data for further processing and visual manipulation.

    Many thanks

    Martin

    Monday, September 16, 2019 12:23 PM

All replies

  • Hi,

    Do you want to get a handle to the MediaPlayerElement/WebView control, then take a screenshot?

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, September 17, 2019 8:33 AM
    Moderator
  • Hi there Alex!

    Simple answer: Kind of yes :)

    More complex answer: Strictly speaking what I want to do is get a video playing in the background of a WPF window. Even more specifically, with shader effects applied to it. I've played with putting a MediaPlayerElement control in the background of my WPF window, but the controls content is rendered on top of all WPF content, even if ordered to the back (certainly on my h/w, which to me is *guess* in line with an xaml island hosting a control in it's own separate hwnd - so doesn't integrate with the wpf's controls rendering). Same with a web control - wanting to take some web content and use as a background.

    So the best idea I could come up with is rendering MediaPlayerElement/WebView off screen and scraping its data into an image/brush/whatever that WPF can then use.

    Don't like that solution as it's extra overhead copying around images/buffers/whatever - maybe someone can come up with a better idea!

    Many thanks

    Martin

    Tuesday, September 17, 2019 8:59 AM
  • Hi,

    take screenshot of WPF application

      public sealed class SnapshotHandler
        {
            [StructLayout(LayoutKind.Sequential)]
            private struct RECT
            {
                public int m_left;
                public int m_top;
                public int m_right;
                public int m_bottom;
            }
    
            [DllImport("user32.dll")]
            private static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
    
            public static void Savesnapshot(IntPtr handle_,string filename)
            {
                RECT windowRect = new RECT();
                GetWindowRect(handle_, ref windowRect);
    
                Int32 width = windowRect.m_right - windowRect.m_left;
                Int32 height = windowRect.m_bottom - windowRect.m_top;
                System.Drawing.Point topLeft = new System.Drawing.Point(windowRect.m_left, windowRect.m_top);
    
                Bitmap b = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(b);
                g.CopyFromScreen(topLeft, new System.Drawing.Point(0, 0), new System.Drawing.Size(width, height));
                b.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
        }
     SnapshotHandler.Savesnapshot(new WindowInteropHelper(this).Handle,"D:\\test.jpg");

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Babbage Wednesday, September 25, 2019 3:28 PM
    • Unmarked as answer by Babbage Thursday, September 26, 2019 9:28 AM
    Tuesday, September 24, 2019 2:48 AM
    Moderator
  • Hi there Alex.

    That helped get me to an initial solution, many thanks - will try and work with this for now.

    To be usable in my case I've had to mix it in with some pixel writing to a writable bitmap, so I can reuse bitmap memory so I don't suddenly have huge amounts of ram constantly being allocated (60fps updates).

    I marked the above as `the answer`, but my initial question is unsolved - I would still like to know though if I can get the hwnd of the MediaPlayerElement and WebView controls themselves, so I can get things more directly than I am right now.

    Many thanks

    Martin

    Wednesday, September 25, 2019 3:28 PM
  • Following this up - this doesn't work for capturing the content of the window if there are other elements (e.g. other windows) overlapping the window on screen - i.e. it literally grabs the screens contents at the _location_ of the window.

    If the window is hidden (for offscreen processing of content) then you can get nothing from it.

    :/

    Many thanks

    Martin

    Thursday, September 26, 2019 9:30 AM
  • Hi,

    try the code:

      public void SaveFrameworkElementToImage(FrameworkElement ui, string filename)
            {
              
                    System.IO.FileStream ms = new System.IO.FileStream(filename, System.IO.FileMode.Create);
                    System.Windows.Media.Imaging.RenderTargetBitmap bmp = new System.Windows.Media.Imaging.RenderTargetBitmap((int)ui.ActualWidth, (int)ui.ActualHeight, 96d, 96d, System.Windows.Media.PixelFormats.Pbgra32);
                    bmp.Render(ui);
                    System.Windows.Media.Imaging.JpegBitmapEncoder encoder = new System.Windows.Media.Imaging.JpegBitmapEncoder();
                    encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp));
                    encoder.Save(ms);
                    ms.Close();
    
                    File.Copy(filename, "D:\\" + filename, true);
             
            }

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, September 27, 2019 2:24 AM
    Moderator