zoukankan      html  css  js  c++  java
  • [C#] 如何截取完整的网页图片

    前言

    有时候浏览到非常有用的网页时,我们会选择将它加入到收藏夹中,但是网站一旦过期,以后就看不到这个网页了。当然也可以将网页打印成PDF文档保存。最新的Windows 10中的Edge浏览器支持将网页保存至OneNote中,但在OneNote中其实是保存了一张当前页面的完整图片。这篇博客将介绍如何使用C#将完整的页面保存成图片。

    实现方式

    使用WinForms中的WebBrowser来保存图片,具体DrawToBitmap方法进行保存。新建一个Console程序(添加System.Windows.Forms),

    [STAThread]
    static void Main(string[] args)
    {
        int width = 800;
        int height = 600;using (WebBrowser browser = new WebBrowser())
        {
            browser.Width = width;
            browser.Height = height;
            browser.ScrollBarsEnabled = false;
            browser.ScriptErrorsSuppressed = true;
    
            browser.DocumentCompleted += OnDocumentCompleted;
    
            browser.Navigate("http://www.cnblogs.com");
    
            Application.Run();
        }
    }
    
    private static void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser browser = (WebBrowser)sender;
    
        using (Graphics graphics = browser.CreateGraphics())
        {
            int dWidth = browser.Document.Body.ScrollRectangle.Width;
    
            int dHeight = browser.Document.Body.ScrollRectangle.Height;
    
            browser.Height = dHeight;
    
            browser.Width = dWidth;
    
            using (Bitmap bitmap = new Bitmap(dWidth, dHeight, graphics))
            {
                Rectangle bounds = new Rectangle(0, 0, dWidth, dHeight);
    
                browser.DrawToBitmap(bitmap, bounds);
    
                bitmap.Save("Screenshot1.png", ImageFormat.Png);
            }
        }
        Application.Exit();
    }

    注意加粗的代码,当页面加载完成后,需要根据网页的大小来调整WebBrowser的大小,否则保存的页面大小就是初始时给WebBrowser设置的大小。

    上述代码中,直接将需要截图的页面写在代码中,如果能够直接读取当前IE/FireFox/Chrome打开的页面,直接截图就完美了。

    改进

    增加获取当前IE/FireFox/Chrome打开的页面,

    代码参考自:https://stackoverflow.com/questions/5317642/retrieve-current-url-from-c-sharp-windows-forms-application

    添加UIAutomationClient和UIAutomationTypes引用,

    public static string GetChromeUrl(Process process)
    {
        if (process == null)
            throw new ArgumentNullException("process");
    
        if (process.MainWindowHandle == IntPtr.Zero)
            return null;
    
        AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
        if (element == null)
            return null;
    
        AutomationElement edit = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
        return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
    }
    
    public static string GetInternetExplorerUrl(Process process)
    {
        if (process == null)
            throw new ArgumentNullException("process");
    
        if (process.MainWindowHandle == IntPtr.Zero)
            return null;
    
        AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
        if (element == null)
            return null;
    
        AutomationElement rebar = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ReBarWindow32"));
        if (rebar == null)
            return null;
    
        AutomationElement edit = rebar.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
    
        return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
    }
    
    public static string GetFirefoxUrl(Process process)
    {
        if (process == null)
            throw new ArgumentNullException("process");
    
        if (process.MainWindowHandle == IntPtr.Zero)
            return null;
    
        AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
        if (element == null)
            return null;
    
        AutomationElement doc = element.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
        if (doc == null)
            return null;
    
        return ((ValuePattern)doc.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
    }

    根据浏览器进程查找当前Active的页面,

    string url = string.Empty;
    
    foreach (Process process in Process.GetProcessesByName("firefox"))
    {
        url = GetFirefoxUrl(process);
        if (url != null)
        {
            // Find the target Url
            break;
        }
    }
    
    foreach (Process process in Process.GetProcessesByName("iexplore"))
    {
        url = GetInternetExplorerUrl(process);
        if (url != null)
        {
            // Find the target Url
            break;
        }
    }
    
    foreach (Process process in Process.GetProcessesByName("chrome"))
    {
        url = GetChromeUrl(process);
        if (url != null)
        {
            // Find the target Url
            break;
        }
    }

    此时就不需要手动的修改需要截图的Url地址了,直接一键截图~

    感谢您的阅读~ 代码点击这里下载。

  • 相关阅读:
    保险
    cron表达式的用法
    Hive 学习记录
    股票的五种估值方法
    AtCoder Beginner Contest 113 A
    ZOJ 4070 Function and Function
    银行业务队列简单模拟 (数据结构题目)
    算法3-7:银行排队
    算法3-5:n阶Hanoi塔问题
    算法3-1:八进制数
  • 原文地址:https://www.cnblogs.com/yang-fei/p/7491203.html
Copyright © 2011-2022 走看看