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