Could someone help me wrap a cef method in cefsharp?

182 views
Skip to first unread message

Bob

unread,
Apr 16, 2014, 12:56:20 AM4/16/14
to cefs...@googlegroups.com
In Cef, on cef_browser.h there is a method called GetImage cef_browser

In the CefSharp.Winforms.WebView h and cpp files (stable 1.27) I was hoping to include that method, so I can call it from c#.

I've learned enough c++ to figure out some of the syntax, but I keep getting stuck with void*
http://pastebin.com/7DRHd974

Any help would be greatly appreciated.

-ep

Per Lundberg

unread,
Apr 16, 2014, 4:53:02 PM4/16/14
to cefs...@googlegroups.com
I don't think that will be possible from pure C#, to be honest; it looks like you have to manually allocate memory and so on (which is very much C/C++-oriented).

Do you mind if I ask what you are trying to do? :)

Best regards,
Per

Bob

unread,
Apr 17, 2014, 10:16:17 AM4/17/14
to cefs...@googlegroups.com
Thank you for helping Per!

You also make me a sad panda.  I was afraid that was the problem.  Myself and my dev lead have minimal c++ experience, but if you have any suggestions on what we would need to do to get this working, I would be so, so, so grateful.

My users are using cef sharp to navigate to arbitrary webpages on the internet, and run some in-house analytics software that we have.  Once they've completed, I need to take a screenshot of the entire web page as it is currently rendered to the user.

I've implemented a cefsharp solution, as both geckofx and IE have bugs in their codebase for screenshooting, but the various webkit implementations are known as more stable.

The webView.DrawScreenToBitmap method is buggy.  It A) only ever returns a white screen bitmap on our systems B) it relies on System.Windows.Forms.Control.DrawScreenToBitmap which is marked as buggy in Microsoft's application (though I'd be okay with it if it worked at all), and C) there appears to be no equivalent in the wpf project, though I am currently developing in your winform branch.

I've played around with the windows API calls for printing to screen and gotten some methods reliably returning the rendered on screen pixels (would you like a pull request?), but nothing that can get me the entire page.

In CEF the GetImage method exposes webkit's internal screen buffer, which makes it the only available method in windows to reliably get the image displayed to the screen, for any .Net browser implementation, for any browser.  The only other alternative is QTWebkit, which wasn't really an option for us, being a .net shop.

CEFGlue has actually already implemented this method in their library (cef1 cefgule.4 branch, currently alpha doesn't compile) cefglue .4, but I don't know enough c++ to make use of the below.

        /// <summary>
        /// Get the raw image data contained in the specified element without performing validation.
        /// The specified |width| and |height| dimensions must match the current element size.
        /// On Windows |buffer| must be width*height*4 bytes in size and represents a BGRA image with an upper-left origin.
        /// This method should only be called on the UI thread.
        /// </summary>
        public bool GetImage(CefPaintElementType type, int width, int height, IntPtr buffer)
        {
            return cef_browser_t.invoke_get_image(this.ptr, (cef_paint_element_type_t)type, width, height, (void*)buffer) != 0;
        }

        /// <summary>
        /// Get the raw image data contained in the specified element without
        /// performing validation. The specified |width| and |height| dimensions
        /// must match the current element size. On Windows |buffer| must be
        /// width*height*4 bytes in size and represents a BGRA image with an
        /// upper-left origin. This function should only be called on the UI
        /// thread.
        /// </summary>
        public IntPtr get_image;
        [UnmanagedFunctionPointer(libcef.Callback), SuppressUnmanagedCodeSecurity]
        public delegate int get_image_delegate(cef_browser_t* self, cef_paint_element_type_t type, int width, int height, void* buffer);

        private static IntPtr s_bp23;
        private static get_image_delegate s_bd23;

        // method slot: 23
        public static int invoke_get_image(cef_browser_t* self, cef_paint_element_type_t type, int width, int height, void* buffer)
        {
            get_image_delegate mdelegate;

            var mptr = self->get_image;
            if (mptr == s_bp23)
            {
                mdelegate = s_bd23;
            }
            else
            {
                mdelegate = (get_image_delegate)Marshal.GetDelegateForFunctionPointer(mptr, typeof(get_image_delegate));
                if (s_bp23 == IntPtr.Zero)
                {
                    s_bd23 = mdelegate;
                    s_bp23 = mptr;
                }
            }

            return mdelegate(self, type, width, height, buffer);
        }

thank you so much in advance for any suggestions or help you could provide.

Bob

Bob

unread,
Apr 17, 2014, 10:22:00 AM4/17/14
to cefs...@googlegroups.com
It appears the link to cefglue I posted in the previous post redirects.  On the screen it redirects to, if you click branches, then you can grab the .4 branch, if you think seeing it would be useful. I haven't actually tried using their implementation.

Thank you again,
Bob
Reply all
Reply to author
Forward
0 new messages