2009-03-31 21 views
3

Ich habe ein WebBrowser-Steuerelement und ich möchte die gesamte Seite in Bild (jede Webseite) gespeichert speichern. Ich habe versucht, IHHTLElementRender-Schnittstelle zu verwenden, aber es funktionierte nicht für alle Webseiten. Vielleicht mache ich etwas falsch, weil der Schnappschuss manchmal die Scroller enthielt und manchmal nur teilweise. Haben Sie ein Arbeitsbeispiel, mit dem Sie die gesamte Webseite in einem Bild speichern können?Wie speichere ich eine Webseite zu Bild

Danke.

+1

Vielleicht sollten Sie fragen: „Wie kann ich einen Screenshot von einem Fenster (mit Scrollen aktiviert)“. ;-) – Cerebrus

Antwort

2

Siehe http://blog.ashmind.com/index.php/2008/09/28/putting-web-snapshots-to-practical-use/ und hier ist der Code: http://ashmind-web-ui.googlecode.com/svn/trunk/AshMind.Web.Snapshots/

Es sollte das korrekt identifizieren Größe die meiste Zeit, aber es ist in keiner Weise eine vollständig getestete und endgültige Lösung.

+0

cool. Es gibt einen Fehler, den ich bereits in diesem Code bemerkt habe. Auf Websites, die mehrere Frames enthalten, z. B. msn.com, tritt das Ereignis "Dokument abgeschlossen" mehrmals auf. Es wird nicht gewartet, bis alle Frames geladen sind. –

+0

Danke. Ich hoffe, dass es dort nicht zu viele Bugs gibt, aber als Beweis für das wird dies wahrscheinlich tun. –

+0

Dieser Code verwendet die nicht unterstützte Methode DrawToBitmap für das WebBrowser-Steuerelement. Wenn Sie beispielsweise den Code mit "http://www.yahoo.com" aufrufen, wird nur ein weißes Bild gezeichnet. – jjxtra

2

Es gibt eine great CodeProject article, die zeigt, wie diese Aufgabe mit der IE-Engine erledigt werden kann. Wenn Sie die Rendering-Engine eines anderen Browsers bevorzugen, ist dies ein guter Ausgangspunkt, um mit dem Lernen zu beginnen. Es gibt auch an addon für Firefox, der dies tun wird, könnten Sie in die Interna von ihm graben, um Einblick zu erhalten, wie man dies in firefox erreicht.

+0

Ich habe versucht, es mit Vista + IE8 zu betreiben. Es hat nicht funktioniert (schwarzer Bildschirm erfasst). Ich habe es noch nicht getestet. –

+0

Ich habe einen Workaround im Kommentarbereich des Artikels gesehen. Ich sollte das auch untersuchen ... –

0

Sie könnten diese Jungs http://webthumb.bluga.net/home und den folgenden Code verwenden. Wenn Sie nur ein paar Bilder pro Monat benötigen, ist es kostenlos, aber sie verlangen ein wenig mehr.

(ich bin in keiner Weise mit ihnen verbundenen, habe ich dies nur in der Vergangenheit)

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 
    } 
0

Wenn die Webseite JS stark beansprucht, zum Beispiel eine Karten-App, werden die vorgestellten Lösungen nicht sehr gut funktionieren.

diesen Code mit Web-Browser Kontrolle effizienter verwendet gefunden, in dem Mangel an besseren ...

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 Qualitypoint Technologies bei http://qualitypoint.blogspot.com/2009/03/c-webbrowser-control-synchronization.html

HTH!

Grüße, byte_slave

Verwandte Themen