【百分求助】网页加载问题

chate 2012-06-13 11:29:53
我的截图程序总是不等网页加载完就截图了,导致一些背景图片不显示。截取腾讯、新浪首页等内容较多的页面时截出的图甚至是空白。能否等网页加载完毕再截图?
我是菜鸟,贴出代码,请高手指导。百分结贴。
Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Bitmap bmp = HtmlToImg.GetHtmlToImg("http://cn.bing.com", 800, 600, 800, 600);//截取不到必应的背景图片,截取页面内容多的页面就变成空白了。
MemoryStream stream = new MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] buff = stream.ToArray();
//保存图片
FileStream fs = new FileStream(Server.MapPath(DateTime.Now.ToString("HHmmss") + ".jpg"), FileMode.Create);
stream.WriteTo(fs);
stream.Close();
fs.Close();
}
}

App_Code/HtmlToImg.cs

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
/// <summary>
/// 生成网页快照
/// </summary>
public class HtmlToImg
{
Bitmap m_Bitmap;
string m_Url;
int m_BrowserWidth, m_BrowserHeight, m_ThumbnailWidth, m_ThumbnailHeight;
public HtmlToImg(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
{
m_Url = Url;
m_BrowserHeight = BrowserHeight;
m_BrowserWidth = BrowserWidth;
m_ThumbnailWidth = ThumbnailWidth;
m_ThumbnailHeight = ThumbnailHeight;
}
public static Bitmap GetHtmlToImg(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
{
HtmlToImg thumbnailGenerator = new HtmlToImg(Url, BrowserWidth, BrowserHeight, ThumbnailWidth, ThumbnailHeight);
return thumbnailGenerator.GenerateHtmlToImgImage();
}
public Bitmap GenerateHtmlToImgImage()
{
Thread m_thread = new Thread(new ThreadStart(_GenerateHtmlToImgImage));
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start();
m_thread.Join();
return m_Bitmap;
}
private void _GenerateHtmlToImgImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;
m_WebBrowser.Navigate(m_Url);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
m_WebBrowser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser m_WebBrowser = (WebBrowser)sender;
m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
m_WebBrowser.ScrollBarsEnabled = false;
m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
m_WebBrowser.BringToFront();
m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
}
}
...全文
544 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
chate 2013-04-25
  • 打赏
  • 举报
回复
引用 23 楼 qldsrx 的回复:
修改WebBrowser_DocumentCompleted函数,添加if判断,判断WebBrowser.ReadyState属性为Complete才进行截图。因为网页的加载往往分为很多步骤,每个步骤都会触发WebBrowser_DocumentCompleted,要判断是否为最后一次触发,就必须看WebBrowser.ReadyState属性: C# code?123……
非常感谢!
_小黑_ 2013-04-09
  • 打赏
  • 举报
回复
我以前做的是获取网页的数据,应该和你的类似,你判断一下背景图片的div是否为null 我以前获取数据的时候也是出现类似的问题
qldsrx 2013-04-09
  • 打赏
  • 举报
回复
修改WebBrowser_DocumentCompleted函数,添加if判断,判断WebBrowser.ReadyState属性为Complete才进行截图。因为网页的加载往往分为很多步骤,每个步骤都会触发WebBrowser_DocumentCompleted,要判断是否为最后一次触发,就必须看WebBrowser.ReadyState属性:

private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    WebBrowser m_WebBrowser = (WebBrowser)sender;
    if(m_WebBrowser.ReadyState == WebBrowserReadyState.Complete)
    {
        m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
        m_WebBrowser.ScrollBarsEnabled = false;
        m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
        m_WebBrowser.BringToFront();
        m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
        m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
    }
}
a3212b12 2013-04-09
  • 打赏
  • 举报
回复
引用 12 楼 showlie 的回复:
原因出在_GenerateHtmlToImgImage和WebBrowser_DocumentCompleted之间的同步问题 WebBrowser文档一加载完成,那么线程函数_GenerateHtmlToImgImage就返回了,也就是线程执行完成,Thread.Join阻塞结束,直接返回Bitmap,而此时WebBrowser_DocumentCompleted的执……
楼主,这个应该是比较好的方法。 我刚好在通讯程序有和楼主类似的问题,目前的解决办法类似于先Navigate打开网页,然后然后等待段时间,再去截图,这样的办法总觉得不可靠。 建议学习 ManualResetEvent 。
chate 2012-07-04
  • 打赏
  • 举报
回复
看来很难办!再顶一次,顶不动了~~
chate 2012-06-24
  • 打赏
  • 举报
回复
哪位高手给个答案啊~~
chate 2012-06-22
  • 打赏
  • 举报
回复
搜索“webbrowser加载完成”有很多结果,可是照搬过来都出现错误,但愿大侠能帮我改一下上面的代码~~
cnfixit 2012-06-21
  • 打赏
  • 举报
回复
你这个问题的关键在于页面是否完全下载完成
DocumentCompleted并不一定准确,有时候会发生不止一次
搜索一下“webbrowser加载完成”
chate 2012-06-21
  • 打赏
  • 举报
回复
没办法解决吗?
蝶恋花雨 2012-06-19
  • 打赏
  • 举报
回复
参考。http://topic.csdn.net/u/20081114/09/9662ae25-cc7e-4973-ab71-93d6ed1b04f4.html
发布一个网页截屏原代码,用于web截屏.图片直接传服务器收藏
chate 2012-06-19
  • 打赏
  • 举报
回复
求助~~~谁能找出原因啊~~~~
chate 2012-06-19
  • 打赏
  • 举报
回复
哪位高手给看一下啊~~
showlie 2012-06-16
  • 打赏
  • 举报
回复
原因出在_GenerateHtmlToImgImage和WebBrowser_DocumentCompleted之间的同步问题
WebBrowser文档一加载完成,那么线程函数_GenerateHtmlToImgImage就返回了,也就是线程执行完成,Thread.Join阻塞结束,直接返回Bitmap,而此时WebBrowser_DocumentCompleted的执行肯定比线程结束完,也就是说Bitmap还没有被截图。
所以,截图总是空白。

解决方法:
1、定义一个ManualResetEvent waiter = new ManualResetEvent(false);
2、用waiter.WaitOne()取代Thread.Join
3、在WebBrowser_DocumentCompleted截图完成后waiter.Set();
licai1210 2012-06-16
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20110223/11/dcb02609-5743-42a0-b259-50da2bc1097a.html

你可以参考这个,估计判断异步比较困难。而很多网站为了提高用户体验却刚好用了异步,所以可能需要用到变通的方式来解决这个问题
licai1210 2012-06-16
  • 打赏
  • 举报
回复
我猜想下,如果页面的一些图片或者其他资料已异步加载的方式显示的话可能就截不到图片了。你可以查查在异步的时候如果你判断页面是否加载完毕
chate 2012-06-16
  • 打赏
  • 举报
回复
谢谢各位!
while (m_browser.ReadyState != WebBrowserReadyState.Complete)这句是判断网页文档是否加载完毕的吧?好像不能判断图片和java等内容的加载情况。在某个地方加上System.Threading.Thread.Sleep(3000);是不是可以弥补一下?

另外showlie能给出具体代码吗?
licai1210 2012-06-15
  • 打赏
  • 举报
回复
    private void _GenerateHtmlToImgImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;
m_WebBrowser.Navigate(m_Url);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (m_WebBrowser.ReadyState == WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
m_WebBrowser.Dispose();
}

这样看看
chate 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete){
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
Application.DoEvents(……
[/Quote]
谢谢!
我基础很差,改了两次都很占内存,几乎死机,等好长时间才截出图来,但都不理想。
改成下面这样,截图显示目标网页无法打开:

private void _GenerateHtmlToImgImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
{
m_WebBrowser.ScrollBarsEnabled = false;//内部浏览器的滚动条
m_WebBrowser.Navigate(m_Url);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
Application.DoEvents();
}
m_WebBrowser.Dispose();
}

再改成下面这样,截出来的是一个黑色矩形:

private void _GenerateHtmlToImgImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;//内部浏览器的滚动条
m_WebBrowser.Navigate(m_Url);
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
{
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
Application.DoEvents();
}
m_WebBrowser.Dispose();
}

是不是我插入代码的位置不对啊?
chate 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
楼主你参考下这篇文章吧
通过WebBrowser网页截图
[/Quote]
这篇文章似乎也是用的这句判断加载,和我的一样:

//浏览器Dom载入完毕
while (m_browser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}

和我的一样,为什么我的截不到网易的图,只是一片空白?我的只能截取页面内容很少的。
把这个页面整个项目下载了,文件很多,没看明白。
licai1210 2012-06-15
  • 打赏
  • 举报
回复
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete){
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
Application.DoEvents();
}
这样试试
加载更多回复(5)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧