How do I save a web page to image

僤鯓⒐⒋嵵緔 提交于 2019-12-18 12:47:24

问题


I have a WebBrowser control and I want to save the whole page viewed to image (any web page). I tried using IHTMLElementRender interface but it didn't work for all web pages. Maybe I'm doing something wrong because sometimes the snapshot included the scrollers and sometimes it was just partial. Do you have a working example that can save the whole web page to an image?

Thanks.


回答1:


See http://blog.ashmind.com/index.php/2008/09/28/putting-web-snapshots-to-practical-use/ and here is the code: http://ashmind-web-ui.googlecode.com/svn/trunk/AshMind.Web.Snapshots/

It should correctly identify the size most of the times, but it is in no way a completely tested and final solution.




回答2:


There is a great CodeProject article that shows hows to accomplish this task using the IE engine. If you prefer to use another browser's rendering engine, this is a good place to start learning. There is also an addon for Firefox which will do this, you could dig into the internals of it to get insight on how to accomplish this in firefox.




回答3:


You could use these guys http://webthumb.bluga.net/home and the following code. If you only need a few images generated per month it is free but they charge a little for more.

(I am in no way affiliated with them, I have just used this in the past)

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
    }



回答4:


If the webpage is heavy on JS, for instance a maps app the solutions presented won't work very well.

Found this code used with Webbrowser control more efficient, in the lack of better...

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++;

   }
}

Credits to QualityPoint Technologies at http://qualitypoint.blogspot.com/2009/03/c-webbrowser-control-synchronization.html

HTH!

Regards, byte_slave



来源:https://stackoverflow.com/questions/701680/how-do-i-save-a-web-page-to-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!