如何将网页保存成图片? 通过copy screen然后写到图片中 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 按那个打印屏幕的键啊,不够长的话就先COPY一屏,拉下来再COPY下一屏...把内容放在画板里拼起来 agree second floor`s opinion 我也问过类似的问题,一直没解决,继续关注中http://community.csdn.net/Expert/topic/3564/3564760.xml?temp=.4594843http://www.sysimage.com/windows/html2image/default.aspx 给出我的思路吧:第一,可以确定要用Windows API 来实现,还要要解决客户区大于屏幕的问题;第二,用InvalidateRect API函数向应用程序窗口发送消息,使之重画指定RECT的客户区,然后用BitBlt拷贝此RECT内的客户区到内存位图里;第三,再InvalidateRect API重画另一片客户区,直至所有客户区都重画完。用此法可以解决客户区大于屏幕的问题只是很初步的想法,这个问题太难了~~ 谢谢大家, FJGoodGood(_FJ_强中强) 的思路也不错,不过这其中还会涉及很多技术细节,继续热切期望中...... 收到你的短消息了.我觉得我的思路完成能满足你的需要.给你一个函数,传入你的网址(本地远程都可以)和要保存的MHTML文件(扩展名MHT)的路径就可以了. public void HtmlToMht(string src, string dst) { CDO.Message msg = new CDO.MessageClass(); CDO.Configuration c = new CDO.ConfigurationClass(); msg.Configuration = c; msg.CreateMHTMLBody(src, CDO.CdoMHTMLFlags.cdoSuppressNone, "", ""); ADODB.Stream stream = msg.GetStream(); stream.SaveToFile(dst, ADODB.SaveOptionsEnum.adSaveCreateOverWrite); }需要添加引用CDO. RockyZhang(Rocky),你好我是这样用的private void button1_Click(object sender, System.EventArgs e){this.HtmlToMht ( this.textBox1.Text, @"c:\\hah.mht");} RockyZhang(Rocky),你好我是这样用的private void button1_Click(object sender, System.EventArgs e){this.HtmlToMht ( "http;//www.21cn.com", @"c:\\hah.mht");}在执行到msg.CreateMHTMLBody(src, CDO.CdoMHTMLFlags.cdoSuppressNone, "", "");这句时捕捉到错误:Interface没有登录!能给我讲讲是什么问题吗?A using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;using System.Runtime.InteropServices;namespace HTML2Image{ /// <summary> /// Form1 的摘要说明。 /// </summary> public class Form1 : System.Windows.Forms.Form { private AxSHDocVw.AxWebBrowser wb; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private object objNull = null; private Bitmap image = null; /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); this.wb.Navigate("about:blank", ref objNull, ref objNull, ref objNull, ref objNull); } /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1)); this.wb = new AxSHDocVw.AxWebBrowser(); this.textBox1 = new System.Windows.Forms.TextBox(); this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.wb)).BeginInit(); this.SuspendLayout(); // // wb // this.wb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.wb.Enabled = true; this.wb.Location = new System.Drawing.Point(8, 8); this.wb.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("wb.OcxState"))); this.wb.Size = new System.Drawing.Size(416, 150); this.wb.TabIndex = 0; this.wb.DocumentComplete += new AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.wb_DocumentComplete); // // textBox1 // this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.textBox1.Location = new System.Drawing.Point(8, 168); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(256, 21); this.textBox1.TabIndex = 1; this.textBox1.Text = "http://"; // // button1 // this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.button1.Location = new System.Drawing.Point(272, 168); this.button1.Name = "button1"; this.button1.TabIndex = 2; this.button1.Text = "Open"; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.button2.Location = new System.Drawing.Point(352, 168); this.button2.Name = "button2"; this.button2.TabIndex = 3; this.button2.Text = "Preview"; this.button2.Click += new System.EventHandler(this.button2_Click); // // Form1 // this.AcceptButton = this.button1; this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(432, 197); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Controls.Add(this.textBox1); this.Controls.Add(this.wb); this.Name = "Form1"; this.Text = "Form1"; ((System.ComponentModel.ISupportInitialize)(this.wb)).EndInit(); this.ResumeLayout(false); } #endregion /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private void SetWBSize(bool full) { this.wb.FullScreen = full; } private void button1_Click(object sender, System.EventArgs e) { this.image = null; SetWBSize(false); this.wb.Visible = true; this.wb.Navigate(this.textBox1.Text, ref objNull, ref objNull, ref objNull, ref objNull); } private void button2_Click(object sender, System.EventArgs e) { SetWBSize(true); DrawImage(); this.wb.Visible = false; this.Refresh(); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint (e); if(this.image != null) { e.Graphics.DrawImage(this.image, 8, 8, this.ClientRectangle.Width - 16, this.ClientRectangle.Height - 44); } } private void DrawImage() { Graphics graphic = this.wb.CreateGraphics(); Size s = new Size(this.ClientRectangle.Width - 16, this.ClientRectangle.Height - 44); this.image = new Bitmap(s.Width, s.Height, graphic); Graphics memGraphic = Graphics.FromImage(image); IntPtr dc1 = graphic.GetHdc(); IntPtr dc2 = memGraphic.GetHdc(); BitBlt(dc2, 0, 0, this.ClientRectangle.Width - 16, this.ClientRectangle.Height - 44, dc1, 0, 0, SRCCOPY); graphic.ReleaseHdc(dc1); memGraphic.ReleaseHdc(dc2); } private const int SRCCOPY = 0xCC0020; [DllImport("gdi32.dll")] private static extern bool BitBlt( IntPtr hdcDest, // handle to destination DC int nXDest, // x-coord of destination upper-left corner int nYDest, // y-coord of destination upper-left corner int nWidth, // width of destination rectangle int nHeight, // height of destination rectangle IntPtr hdcSrc, // handle to source DC int nXSrc, // x-coordinate of source upper-left corner int nYSrc, // y-coordinate of source upper-left corner System.Int32 dwRop // raster operation code ); private void wb_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e) { this.Text = "完成 " + e.uRL.ToString(); } }} 这个是刚才写的,FJGoodGood(_FJ_强中强)所说的,完整的拼凑出一张图来比较麻烦还有就是把WebBrowser的隐藏后好像就抓不到图了 heroqxn(Brook) 做得不错,不过有两个问题需要解决啊:1)取不到客户区之外的图像2)如果界面上盖了一个窗口,会把那个窗口也拷贝下来,比如我开了一个任务管理器(设置了前端显示),就把这个窗口也拷贝了。 我测过了,没问题.this.HtmlToMht("http://www.csdn.net","c:\\test.mht"); 谢谢FJGoodGood, 其实这两个问题都是一个原因造成的,还没找到解决办法。 to RockyZhang(Rocky) :mht是什么文件格式啊?挺新鲜,可否介绍一下? 谢谢 RockyZhang(Rocky)确实可以,是我粗心,敲错了网址字符。这个方法真不错,我试过了,挺好。To:heroqxn(Brook) 你好,你的方法我也正在调试现在遇到一些问题:1、我将AxSHDocVw.dll引用进来,可是不能在工具面板上添加,是不是没有可显示控件?2、我参照你的代码将所有wb部分都Copy进去,编译通过,但运行到public Form1() { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); this.wb.Navigate("about:blank", ref objNull, ref objNull, ref objNull, ref objNull); }中的this.wb.Navigate("about:blank", ref objNull, ref objNull, ref objNull, ref objNull);时,报错“在axshdocvw.dll处,'InvalidActiveXStateException'的Handle没有被引用的异常发生。”我想可能是我导入AxSHDocVw.dll的问题,请指正。谢谢! 谢谢heroqxn(Brook),我调试出来了。确实是导入AxSHDocVw.dll的问题。再次谢谢大家帮忙。 变量名如何拼接 C#编辑DataGridView后回车赋值 急急急!!! 对c#索引器的理解 在做鼠标键的小东西,,遇到问题··· 【100】在线等:DataGrid中的所有数据导出到excel中去 有分页功能 鼠标拖动问题? 查询语句书写格式(c#) 怎样可以修改XML?? 把一个帖子发在 c++专区,结果被整的很惨,请大家为我报仇!! 网上聊天的小程序,怎么实现通过代理上网的双方的联络? 请推荐邮件收发管理控件... c# 菜鸟问题 偶还有的所有分 呵呵 也只有六十分
http://www.sysimage.com/windows/html2image/default.aspx
第二,用InvalidateRect API函数向应用程序窗口发送消息,使之重画指定RECT的客户区,然后用BitBlt拷贝此RECT内的客户区到内存位图里;
第三,再InvalidateRect API重画另一片客户区,直至所有客户区都重画完。用此法可以解决客户区大于屏幕的问题只是很初步的想法,这个问题太难了~~
我觉得我的思路完成能满足你的需要.
给你一个函数,传入你的网址(本地远程都可以)和要保存的MHTML文件(扩展名MHT)的路径就可以了.
public void HtmlToMht(string src, string dst)
{
CDO.Message msg = new CDO.MessageClass();
CDO.Configuration c = new CDO.ConfigurationClass();
msg.Configuration = c;
msg.CreateMHTMLBody(src, CDO.CdoMHTMLFlags.cdoSuppressNone, "", "");
ADODB.Stream stream = msg.GetStream();
stream.SaveToFile(dst, ADODB.SaveOptionsEnum.adSaveCreateOverWrite);
}需要添加引用CDO.
private void button1_Click(object sender, System.EventArgs e)
{
this.HtmlToMht ( this.textBox1.Text, @"c:\\hah.mht");
}
private void button1_Click(object sender, System.EventArgs e)
{
this.HtmlToMht ( "http;//www.21cn.com", @"c:\\hah.mht");
}在执行到
msg.CreateMHTMLBody(src, CDO.CdoMHTMLFlags.cdoSuppressNone, "", "");
这句时
捕捉到错误:Interface没有登录!能给我讲讲是什么问题吗?A
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;namespace HTML2Image
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private AxSHDocVw.AxWebBrowser wb;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private object objNull = null;
private Bitmap image = null;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null; public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent(); this.wb.Navigate("about:blank", ref objNull, ref objNull, ref objNull, ref objNull);
} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.wb = new AxSHDocVw.AxWebBrowser();
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.wb)).BeginInit();
this.SuspendLayout();
//
// wb
//
this.wb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.wb.Enabled = true;
this.wb.Location = new System.Drawing.Point(8, 8);
this.wb.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("wb.OcxState")));
this.wb.Size = new System.Drawing.Size(416, 150);
this.wb.TabIndex = 0;
this.wb.DocumentComplete += new AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.wb_DocumentComplete);
//
// textBox1
//
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox1.Location = new System.Drawing.Point(8, 168);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(256, 21);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "http://";
//
// button1
//
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.button1.Location = new System.Drawing.Point(272, 168);
this.button1.Name = "button1";
this.button1.TabIndex = 2;
this.button1.Text = "Open";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.button2.Location = new System.Drawing.Point(352, 168);
this.button2.Name = "button2";
this.button2.TabIndex = 3;
this.button2.Text = "Preview";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AcceptButton = this.button1;
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(432, 197);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.wb);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.wb)).EndInit();
this.ResumeLayout(false); }
#endregion /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
} private void SetWBSize(bool full)
{
this.wb.FullScreen = full;
} private void button1_Click(object sender, System.EventArgs e)
{
this.image = null;
SetWBSize(false);
this.wb.Visible = true;
this.wb.Navigate(this.textBox1.Text, ref objNull, ref objNull, ref objNull, ref objNull);
} private void button2_Click(object sender, System.EventArgs e)
{
SetWBSize(true);
DrawImage();
this.wb.Visible = false;
this.Refresh();
} protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
if(this.image != null)
{
e.Graphics.DrawImage(this.image, 8, 8, this.ClientRectangle.Width - 16, this.ClientRectangle.Height - 44);
}
} private void DrawImage()
{
Graphics graphic = this.wb.CreateGraphics();
Size s = new Size(this.ClientRectangle.Width - 16, this.ClientRectangle.Height - 44);
this.image = new Bitmap(s.Width, s.Height, graphic);
Graphics memGraphic = Graphics.FromImage(image);
IntPtr dc1 = graphic.GetHdc();
IntPtr dc2 = memGraphic.GetHdc();
BitBlt(dc2, 0, 0, this.ClientRectangle.Width - 16, this.ClientRectangle.Height - 44, dc1, 0, 0, SRCCOPY);
graphic.ReleaseHdc(dc1);
memGraphic.ReleaseHdc(dc2);
} private const int SRCCOPY = 0xCC0020; [DllImport("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
); private void wb_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
this.Text = "完成 " + e.uRL.ToString();
} }
}
2)如果界面上盖了一个窗口,会把那个窗口也拷贝下来,比如我开了一个任务管理器(设置了前端显示),就把这个窗口也拷贝了。
this.HtmlToMht("http://www.csdn.net","c:\\test.mht");
To:heroqxn(Brook)
你好,你的方法我也正在调试
现在遇到一些问题:
1、我将AxSHDocVw.dll引用进来,可是不能在工具面板上添加,是不是没有可显示控件?
2、我参照你的代码将所有wb部分都Copy进去,编译通过,但运行到
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent(); this.wb.Navigate("about:blank", ref objNull, ref objNull, ref objNull, ref objNull);
}中的
this.wb.Navigate("about:blank", ref objNull, ref objNull, ref objNull, ref objNull);
时,报错“在axshdocvw.dll处,'InvalidActiveXStateException'的Handle没有被引用的异常发生。”我想可能是我导入AxSHDocVw.dll的问题,请指正。谢谢!