如何将网页保存为图像

时间:2009-03-31 15:49:56

标签: c# .net winforms webbrowser-control mshtml

我有一个WebBrowser控件,我想保存查看到图像的整个页面(任何网页)。 我尝试使用IHTMLElementRender接口,但它并不适用于所有网页。也许我做错了,因为有时快照包括滚动条,有时它只是部分。 你有一个可以将整个网页保存到图像的工作示例吗?

感谢。

4 个答案:

答案 0 :(得分:2)

有一个great CodeProject article显示使用IE引擎完成此任务的方法。如果您更喜欢使用其他浏览器的渲染引擎,那么这是一个开始学习的好地方。还有an addon用于Firefox,你可以深入了解它的内部,以深入了解如何在Firefox中实现这一目标。

答案 1 :(得分:2)

参见http://blog.ashmind.com/index.php/2008/09/28/putting-web-snapshots-to-practical-use/ 这是代码: http://ashmind-web-ui.googlecode.com/svn/trunk/AshMind.Web.Snapshots/

它应该在大多数情况下正确识别大小,但它绝不是完全测试和最终的解决方案。

答案 2 :(得分:0)

您可以使用这些人http://webthumb.bluga.net/home和以下代码。如果您每个月只需要生成一些图像,那么它是免费的,但是它们会收取更多费用。

(我与他们没有任何关系,我过去刚刚使用过这个)

public enum OutputType
    {
        Png,
        Jpg
    }

    public interface IWebThumbAPI
    {
        int Delay { get; set; }
        int Width { get; set; }
        int Height { get; set; }
        OutputType OutputType { get; set; }
        WebThumbAPI Get(string url);
        WebThumbAPI Get(string url, int x, int y, int width, int height);
        System.Drawing.Image SaveSize(WebThumbSize webThumbSize);
    }

    public class WebThumbAPI : IWebThumbAPI
    {
        private readonly string apiKey;
        private IList<WebThumbResponse> webThumbResponse;
        private string jobId;
        private string ApiUrl { get; set; }
        public int Delay { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public OutputType OutputType { get; set; }

        public WebThumbAPI(string apiKey)
            : this(apiKey, "")
        {
        }

        public WebThumbAPI(string apiKey, string jobId)
        {
            this.apiKey = apiKey;
            OutputType = OutputType.Png;
            Width = 1024;
            Height = 768;
            Delay = 5;
            ApiUrl = "http://webthumb.bluga.net/api.php";
            this.jobId = jobId;
        }

        public WebThumbAPI Get(string url)
        {
            return Get(url, 0, 0, 400, 200);
        }

        public WebThumbAPI Get(string url, int x, int y, int width, int height)
        {
            var outputType = OutputType == OutputType.Jpg ? "jpg" : "png";

            var doc = new XDocument(
                new XElement("webthumb",
                            new XElement("apikey", apiKey),
                             new XElement("request",
                                                 new XElement("url", url),
                                                 new XElement("outputType", outputType),
                                                 new XElement("width", Width),
                                                 new XElement("height", Height),
                                                 new XElement("delay", Delay),
                                                 new XElement("excerpt",
                                                     new XElement("x", x),
                                                     new XElement("y", y),
                                                     new XElement("width", width),
                                                     new XElement("height", height)))
                    )
                );

            var request = getRequest(doc.ToString());
            var webResponse = (HttpWebResponse)request.GetResponse();
            if (webResponse.ContentType == "text/xml")
            {
                var stream = webResponse.GetResponseStream();
                var response = XDocument.Load(XmlReader.Create(stream));
                webThumbResponse = (from xml in response.Descendants("job")
                                    select new WebThumbResponse
                                    {
                                        Estimate = (int)xml.Attribute("estimate"),
                                        Time = (DateTime)xml.Attribute("time"),
                                        Url = (string)xml.Attribute("url"),
                                        Cost = (int)xml.Attribute("cost"),
                                        Job = (string)xml.Value
                                    }).ToList();
                stream.Close();
                if (webThumbResponse.Count == 0)
                    jobId = "-1";
                else
                {
                    jobId = webThumbResponse[0].Job;
                    Thread.Sleep(webThumbResponse[0].Estimate * 1000);
                }

            }
            else
            {
                throw new InvalidOperationException("Failed request");
            }
            return this;
        }

        public System.Drawing.Image SaveSize(WebThumbSize webThumbSize)
        {
            if (jobId == "-1")
                return defaultImage(webThumbSize);
            var doc = new XDocument(
                new XElement("webthumb",
                            new XElement("apikey", apiKey),
                             new XElement("fetch",
                                                 new XElement("job", jobId),
                                                 new XElement("size", Enum.GetName(typeof(WebThumbSize), webThumbSize).ToLower())
                                                 )
                    )
                );
            var request = getRequest(doc.ToString());
            var webResponse = (HttpWebResponse)request.GetResponse();
            var stream = webResponse.GetResponseStream();

            Image image = null;
            try
            {
                image = System.Drawing.Image.FromStream(stream);
            }
            catch
            {
                image = defaultImage(webThumbSize);

            }
            return image;
        }

        private Image defaultImage(WebThumbSize webThumbSize)
        {
            var s = getSize(webThumbSize);
            var b = new Bitmap(s.Width, s.Height);
            var im = Image.FromHbitmap(b.GetHbitmap());
            var gr = System.Drawing.Graphics.FromImage(im);
            gr.Clear(Color.White);
            gr.Dispose();
            return im;
        }

        private static System.Drawing.Size getSize(WebThumbSize size)
        {
            switch (size)
            {
                case WebThumbSize.Small:
                    return new Size(80, 60);
                case WebThumbSize.Excerpt:
                    return new Size(400, 200);
                default:
                    return new Size(1, 1);
            }
        }

        private HttpWebRequest getRequest(string xml)
        {
            var request = (HttpWebRequest)WebRequest.Create(ApiUrl);
            request.Method = "POST";
            request.Timeout = 20000;
            request.ContentType = "text/xml";
            request.UserAgent = @"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418.8 (KHTML, like Gecko) Safari/419.3";
            request.KeepAlive = false;
            request.Pipelined = false;

            Stream newStream = request.GetRequestStream();
            var encoding = new ASCIIEncoding();
            byte[] data = encoding.GetBytes(xml);
            newStream.Write(data, 0, data.Length);
            newStream.Close();
            return request;
        }
    }

    public class WebThumbResponse
    {
        public DateTime Time;
        public string Job;
        public string Url;
        public int Cost;
        public int Estimate { get; set; }
    }

    public enum WebThumbSize
    {
        Small,
        Medium,
        Medium2,
        Large,
        Excerpt
    }

答案 3 :(得分:0)

如果网页上的JS很重,例如地图应用程序,提供的解决方案将无法正常运行。

发现此代码与Webbrowser控件一起使用效率更高,缺乏更好的...

private void waitTillLoad(WebBrowser webBrowser1)
{
   WebBrowserReadyState loadStatus;

   //wait till beginning of loading next page 
   int waittime = 100000;
   int counter = 0;
   while (true)
   {
       loadStatus = webBrowser1.ReadyState;
       Application.DoEvents();

       if ((counter > waittime) || (loadStatus == WebBrowserReadyState.Uninitialized) || (loadStatus == WebBrowserReadyState.Loading) || (loadStatus == WebBrowserReadyState.Interactive))
       {
           break;
       }
       counter++;
   }

   //wait till the page get loaded.
   counter = 0;
   while (true)
   {
       loadStatus = webBrowser1.ReadyState;
       Application.DoEvents();

       if (loadStatus == WebBrowserReadyState.Complete)
       {
           break;
       }
       counter++;

   }
}

http://qualitypoint.blogspot.com/2009/03/c-webbrowser-control-synchronization.html

致QualityPoint Technologies的致谢

HTH!

此致 byte_slave