CEF截图

记录目前两种实现方式

[DllImport("user32.dll")]
        private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);

        public void WriteBmp(string bmpPath)
        {

            int screenWidth = webbrowser.Document.Body.ScrollRectangle.Width;
            int screenHeight = webbrowser.Document.Body.ScrollRectangle.Height;

            IntPtr myIntptr = webbrowser.Handle;
            int hwndInt = myIntptr.ToInt32();
            IntPtr hwnd = myIntptr;

            // Set hdc to the bitmap

            Bitmap bm = new Bitmap(screenWidth, screenHeight);
            Graphics g = Graphics.FromImage(bm);
            IntPtr hdc = g.GetHdc();

            // Snapshot the WebBrowser

            bool result = PrintWindow(hwnd, hdc, 0);
            g.ReleaseHdc(hdc);
            g.Flush();

            // Save the bitmap, if successful

            if (result == true)
                bm.Save(bmpPath);
        }

第二种

public static class ApiConstants
    {
        public const int SRCCOPY = 13369376;
    }

    public static class Utilities
    {
        public static Image CaptureScreen()
        {
            return CaptureWindow(User32.GetDesktopWindow());
        }

        public static Image CaptureWindow(IntPtr handle)
        {

            IntPtr hdcSrc = User32.GetWindowDC(handle);

            RECT windowRect = new RECT();
            User32.GetWindowRect(handle, ref windowRect);

            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;

            IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
            IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);

            IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
            Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ApiConstants.SRCCOPY);
            Gdi32.SelectObject(hdcDest, hOld);
            Gdi32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);

            Image image = Image.FromHbitmap(hBitmap);
            Gdi32.DeleteObject(hBitmap);

            return image;
        }
    }

    public static class User32
    {
        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
        [DllImport("user32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
    }

    public class Gdi32
    {
        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}

引用https://www.cnblogs.com/jackhuclan/archive/2012/04/23/1909301.html

新增

第三种,使用前端库截图, 这里截图直接是指定元素的全图,包括滚动条不可见部分,避免了使用windows句柄截图只能截取可视区域。

dom-to-image

添加引用

<script src="dom-to-image/dom-to-image.js"></script>

添加截图方法

function shotScreenAsync() {
  return new Promise((resolve, rejece) => {
    var appElement = document.getElementById('app');
    domtoimage.toPng(appElement, {
      bgcolor: "#ffffff",
      style: {
        overflow: ""
      }
    }).then(data => {
      resolve(data);
    }).catch(error => {
        rejece(error)
      });
  })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CefSharp是CEF在.NET平台下的封装,它提供了一个简单的方式来在.NET程序中嵌入Chromium浏览器。 在CefSharp中,我们可以通过调用CefBrowser的GetHost方法获取到CefBrowserHost对象,然后通过调用CefBrowserHost的GetImage方法来获取当前网页的截图。但是,对于超长网页,由于GetImage方法只能获取当前可视区域的截图,因此我们需要进行一些额外的操作才能获取整个网页的截图。 具体方法如下: 1. 获取网页高度 ``` int totalHeight = (int)(browser.ExecuteScriptAsync("return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight);").Result); ``` 这里我们调用JavaScript代码来获取网页的高度。 2. 分段获取截图 将整个网页分为多个部分,分别获取每个部分的截图,然后将这些截图拼接起来就可以得到整个网页的截图。 ``` int partHeight = 32767; // 每个部分的高度 int yOffset = 0; Bitmap bitmap = new Bitmap(1, 1); Graphics graphics = Graphics.FromImage(bitmap); while (yOffset < totalHeight) { int height = Math.Min(partHeight, totalHeight - yOffset); int width = (int)(browser.Width / browser.ZoomLevel); int x = (int)(browser.HorizontalScroll.Value / browser.ZoomLevel); int y = (int)((yOffset + browser.VerticalScroll.Value) / browser.ZoomLevel); // 获取当前部分的截图 Bitmap partBitmap = new Bitmap(width, height, graphics); Rectangle rect = new Rectangle(x, y, width, height); graphics.CopyFromScreen(browser.PointToScreen(rect), new Point(0, 0), rect.Size); partBitmap = partBitmap.Clone(new Rectangle(0, 0, partBitmap.Width, partBitmap.Height), PixelFormat.Format32bppArgb); // 拼接截图 fullBitmap = CombineBitmaps(fullBitmap, partBitmap, yOffset); yOffset += partHeight; } ``` 在以上代码中,我们使用了CombineBitmaps方法来将多个部分的截图拼接起来。 ``` private static Bitmap CombineBitmaps(Bitmap bitmap1, Bitmap bitmap2, int yOffset) { if (bitmap1 == null) { return bitmap2; } Bitmap bitmap = new Bitmap(bitmap1.Width, yOffset + bitmap2.Height); using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawImage(bitmap1, new Rectangle(0, 0, bitmap1.Width, bitmap1.Height)); g.DrawImage(bitmap2, new Rectangle(0, yOffset, bitmap2.Width, bitmap2.Height)); } return bitmap; } ``` 通过以上方法,我们就可以实现获取超长网页的截图了。需要注意的是,如果网页过长,可能会出现内存不足的问题,因此我们可以根据实际情况调整每个部分的高度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值