背景
最近再做一个需求,需要对网页生成预览图,如下图

但是网页千千万,总不能一个个打开,截图吧;于是想着能不能使用代码来实现网页的截图。其实要实现c#教程这个功能,无非就是要么实现一个仿真浏览器,要么调用系统浏览器,再进行截图操作。

代码实现
1、启用线程Thread

void startPrintScreen(ScreenShotParam requestParam){Thread thread = new Thread(new ParameterizedThreadStart(do_PrintScreen));thread.SetApartmentState(ApartmentState.STA);thread.Start(requestParam);if (requestParam.Wait){thread.Join();FileInfo result = new FileInfo(requestParam.SavePath);long minSize = 1 * 1024;// 太小可能是空白圖,重抓int maxRepeat = 2;    while ((!result.Exists || result.Length <= minSize) && maxRepeat > 0){thread = new Thread(new ParameterizedThreadStart(do_PrintScreen));thread.SetApartmentState(ApartmentState.STA);thread.Start(requestParam);thread.Join();maxRepeat--;}}}

2、模拟浏览器WebBrowser

void do_PrintScreen(object param){try{ScreenShotParam screenShotParam = (ScreenShotParam)param;string requestUrl = screenShotParam.Url;string savePath = screenShotParam.SavePath;WebBrowser wb = new WebBrowser();wb.ScrollBarsEnabled = false;wb.ScriptErrorsSuppressed = true;wb.Navigate(requestUrl);logger.Debug("wb.Navigate");DateTime startTime = DateTime.Now;TimeSpan waitTime = new TimeSpan(0, 0, 0, 10, 0);// 10 secondwhile (wb.ReadyState != WebBrowserReadyState.Complete){Application.DoEvents();if (DateTime.Now - startTime > waitTime){wb.Dispose();logger.Debug("wb.Dispose() timeout");return;}}wb.Width = screenShotParam.Left + screenShotParam.Width + screenShotParam.Left; // wb.Document.Body.ScrollRectangle.Width (避掉左右側的邊線);wb.Height = screenShotParam.Top + screenShotParam.Height; // wb.Document.Body.ScrollRectangle.Height;wb.ScrollBarsEnabled = false;wb.Document.Body.Style = "overflow:hidden";//hide scroll barvar doc = (wb.Document.DomDocument) as mshtml.IHTMLDocument2;var style = doc.createStyleSheet("", 0);style.cssText = @"img { border-style: none; }";Bitmap bitmap = new Bitmap(wb.Width, wb.Height);wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));wb.Dispose();logger.Debug("wb.Dispose()");bitmap = CutImage(bitmap, new Rectangle(screenShotParam.Left, screenShotParam.Top, screenShotParam.Width, screenShotParam.Height));bool needResize = screenShotParam.Width > screenShotParam.ResizeMaxWidth || screenShotParam.Height > screenShotParam.ResizeMaxWidth;if (needResize){double greaterLength = bitmap.Width > bitmap.Height ? bitmap.Width : bitmap.Height;double ratio = screenShotParam.ResizeMaxWidth / greaterLength;bitmap = Resize(bitmap, ratio);}bitmap.Save(savePath, System.Drawing.Imaging.ImageFormat.Gif);bitmap.Dispose();logger.Debug("bitmap.Dispose();");logger.Debug("finish");}catch (Exception ex){logger.Info($"exception: {ex.Message}");}}

3、截图操作

private static Bitmap CutImage(Bitmap source, Rectangle section){// An empty bitmap which will hold the cropped imageBitmap bmp = new Bitmap(section.Width, section.Height);//using (Bitmap bmp = new Bitmap(section.Width, section.Height)){Graphics g = Graphics.FromImage(bmp);// Draw the given area (section) of the source image// at location 0,0 on the empty bitmap (bmp)g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);return bmp;}}private static Bitmap Resize(Bitmap originImage, Double times){int width = Convert.ToInt32(originImage.Width * times);int height = Convert.ToInt32(originImage.Height * times);return ResizeProcess(originImage, originImage.Width, originImage.Height, width, height);}

完整代码

public static string ScreenShotAndSaveAmazonS3(string account, string locale, Guid rule_ID, Guid template_ID){//新的Templatevar url = string.Format("https://xxxx/public/previewtemplate?showTemplateName=0&locale={0}&inputTemplateId={1}&inputThemeId=&Account={2}",locale,template_ID,account);var tempPath = Tools.GetAppSetting("TempPath");//路徑準備var userPath = AmazonS3.GetS3UploadDirectory(account, locale, AmazonS3.S3SubFolder.Template);var fileName = string.Format("{0}.gif", template_ID);var fullFilePath = Path.Combine(userPath.LocalDirectoryPath, fileName);logger.Debug("userPath: {0}, fileName: {1}, fullFilePath: {2}, url:{3}", userPath, fileName, fullFilePath, url);//開始截圖,並暫存在本機var screen = new Screen();screen.ScreenShot(url, fullFilePath);//將截圖,儲存到 Amazon S3//var previewImageUrl = AmazonS3.UploadFile(fullFilePath, userPath.RemotePath + fileName);return string.Empty;}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace PrintScreen.Common
{public class Screen{protected static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();public void ScreenShot(string url, string path, int width = 400, int height = 300, int left = 50, int top = 50, int resizeMaxWidth = 200, int wait = 1){if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(path)){ScreenShotParam requestParam = new ScreenShotParam{Url = url,SavePath = path,Width = width,Height = height,Left = left,Top = top,ResizeMaxWidth = resizeMaxWidth,Wait = wait != 0};startPrintScreen(requestParam);}}void startPrintScreen(ScreenShotParam requestParam){Thread thread = new Thread(new ParameterizedThreadStart(do_PrintScreen));thread.SetApartmentState(ApartmentState.STA);thread.Start(requestParam);if (requestParam.Wait){thread.Join();FileInfo result = new FileInfo(requestParam.SavePath);long minSize = 1 * 1024;// 太小可能是空白圖,重抓int maxRepeat = 2;    while ((!result.Exists || result.Length <= minSize) && maxRepeat > 0){thread = new Thread(new ParameterizedThreadStart(do_PrintScreen));thread.SetApartmentState(ApartmentState.STA);thread.Start(requestParam);thread.Join();maxRepeat--;}}}void do_PrintScreen(object param){try{ScreenShotParam screenShotParam = (ScreenShotParam)param;string requestUrl = screenShotParam.Url;string savePath = screenShotParam.SavePath;WebBrowser wb = new WebBrowser();wb.ScrollBarsEnabled = false;wb.ScriptErrorsSuppressed = true;wb.Navigate(requestUrl);logger.Debug("wb.Navigate");DateTime startTime = DateTime.Now;TimeSpan waitTime = new TimeSpan(0, 0, 0, 10, 0);// 10 secondwhile (wb.ReadyState != WebBrowserReadyState.Complete){Application.DoEvents();if (DateTime.Now - startTime > waitTime){wb.Dispose();logger.Debug("wb.Dispose() timeout");return;}}wb.Width = screenShotParam.Left + screenShotParam.Width + screenShotParam.Left; // wb.Document.Body.ScrollRectangle.Width (避掉左右側的邊線);wb.Height = screenShotParam.Top + screenShotParam.Height; // wb.Document.Body.ScrollRectangle.Height;wb.ScrollBarsEnabled = false;wb.Document.Body.Style = "overflow:hidden";//hide scroll barvar doc = (wb.Document.DomDocument) as mshtml.IHTMLDocument2;var style = doc.createStyleSheet("", 0);style.cssText = @"img { border-style: none; }";Bitmap bitmap = new Bitmap(wb.Width, wb.Height);wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));wb.Dispose();logger.Debug("wb.Dispose()");bitmap = CutImage(bitmap, new Rectangle(screenShotParam.Left, screenShotParam.Top, screenShotParam.Width, screenShotParam.Height));bool needResize = screenShotParam.Width > screenShotParam.ResizeMaxWidth || screenShotParam.Height > screenShotParam.ResizeMaxWidth;if (needResize){double greaterLength = bitmap.Width > bitmap.Height ? bitmap.Width : bitmap.Height;double ratio = screenShotParam.ResizeMaxWidth / greaterLength;bitmap = Resize(bitmap, ratio);}bitmap.Save(savePath, System.Drawing.Imaging.ImageFormat.Gif);bitmap.Dispose();logger.Debug("bitmap.Dispose();");logger.Debug("finish");}catch (Exception ex){logger.Info($"exception: {ex.Message}");}}private static Bitmap CutImage(Bitmap source, Rectangle section){// An empty bitmap which will hold the cropped imageBitmap bmp = new Bitmap(section.Width, section.Height);//using (Bitmap bmp = new Bitmap(section.Width, section.Height)){Graphics g = Graphics.FromImage(bmp);// Draw the given area (section) of the source image// at location 0,0 on the empty bitmap (bmp)g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);return bmp;}}private static Bitmap Resize(Bitmap originImage, Double times){int width = Convert.ToInt32(originImage.Width * times);int height = Convert.ToInt32(originImage.Height * times);return ResizeProcess(originImage, originImage.Width, originImage.Height, width, height);}private static Bitmap ResizeProcess(Bitmap originImage, int oriwidth, int oriheight, int width, int height){Bitmap resizedbitmap = new Bitmap(width, height);//using (Bitmap resizedbitmap = new Bitmap(width, height)){Graphics g = Graphics.FromImage(resizedbitmap);g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;g.Clear(Color.Transparent);g.DrawImage(originImage, new Rectangle(0, 0, width, height), new Rectangle(0, 0, oriwidth, oriheight), GraphicsUnit.Pixel);return resizedbitmap;}}}class ScreenShotParam{public string Url { get; set; }public string SavePath { get; set; }public int Width { get; set; }public int Height { get; set; }public int Left { get; set; }public int Top { get; set; }/// <summary>/// 長邊縮到指定長度/// </summary>public int ResizeMaxWidth { get; set; }public bool Wait { get; set; }}}

效果

以上就是c# 实现网页加载后将页面截取为长图片的详细内容

c# 实现网页加载后将页面截取为长图片相关推荐

  1. C#实现网页加载后将页面截取成长图片 | Playwright版

    前言 如何将网页生成预览图? 要实现这个功能,可以用WebBrowser组件模拟浏览器,或者使用系统浏览器访问网页,再进行截图操作. 但是,这样需要编写大量的控制代码. 工欲善其事,必先利其器! 利用 ...

  2. C#实现网页加载后将页面截取成长图片

    背景 最近再做一个需求,需要对网页生成预览图,如下图 但是网页千千万,总不能一个个打开,截图吧:于是想着能不能使用代码来实现网页的截图.其实要实现这个功能,无非就是要么实现一个仿真浏览器,要么调用系统 ...

  3. linux优化网页加载过程,HTML页面加载和解析流程 介绍

    1.浏览器加载和渲染html的顺序 1.1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的. 1.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相 ...

  4. python爬虫获取的网页数据为什么要加[0-[Python爬虫] 等待网页加载后再获取内容...

    0x0 背景 最近在学习Python爬虫的相关知识,主要是之前有一个小idea想要用Python实现,沉寂了一年,近期终于下定决心要利用假期时间首要解决此项任务,不然拖到最后都没完成,自己遗憾不说,还 ...

  5. php 载入css就可以显示,如何在进度条加载后显示页面

    1.思路:加入很多图片,以延迟加载时间,实现加载完后显示图片.定义一个外层p,覆盖住图片,在内层p中引入加载时显示的图片,让内层p居中在页面上,利用setInterval定时器设置3秒后将外层p隐藏, ...

  6. 【vue】数据加载后渲染页面

    vue 想要先加载完所有数据再渲染页面 使用v-if来控制 先设置showCard为false,内容card为"" 请求成功后设置showCard为true,内容card为请求得到 ...

  7. htmlunit爬取js异步加载后的页面

    直接上代码: 一. index.html  调用后台请求获取content中的内容. <html> <head><script type="text/javas ...

  8. android动态图片适配,Android适配利用webview加载后图片显示过大的问题解决

    前言 最近在开发过程中,需要用webview控件来展示文章的详情页面,流程是通过请求后台数据,然后用控件加载,而后台返回的文章详情页面是直接网页端使用的,并没有对移动端进行适配,导致webview加载 ...

  9. 文档已完成加载后执行document write整个 HTML 页面将被覆盖

    看js文档输出时这样警告: "请使用 document.write() 仅仅向文档输出写内容.如果在文档已完成加载后执行 document.write,整个 HTML 页面将被覆盖" ...

最新文章

  1. 这24个高频存储问题,你一定要知道!如何不停机,安全更换数据库?大厂都怎么做MySQL到Redis同步的?...
  2. Python使用scipy包将稀疏矩阵保存为Mtx格式和npz格式文件实战
  3. gdb调试 print打印不出变量值或者不准确
  4. eclipse 工程复制
  5. python画五角星-python画五角星和六角星程序 | 学步园
  6. HDU3338 Kakuro Extension(最大流+思维构图)
  7. 自定义的html radio button的样式
  8. 我的第一场比赛——金马五校赛
  9. 数据管理系统 php,dms: 数据管理系统;采用mvc模型,存php原生操作无模板引擎;响应式前端框架huiadmin套用,扁平化风格,兼容移动端;...
  10. Unity接入海康威视门禁(获取门禁状态信息、门禁反控等)
  11. 几款在线脑图制作工具
  12. Python实践—微信远程控制电脑
  13. 计算机毕业设计Java毕业论文答辩管理系统(源码+系统+mysql数据库+lw文档)
  14. 2013年第十九届全国青少年信息学奥林匹克联赛初赛
  15. 用mysql触发器做数据统计
  16. 【c51】LCD1602__num++显示 (超详细)
  17. android app定时提醒,安卓手机上有没有每10分钟间隔定时提醒一次的便签app软件?...
  18. 共享 || 32份美妆行业报告
  19. 大数据存储引擎 NoSQL极简教程 An Introduction to Big Data: NoSQL
  20. Android开发艺术探索读书笔记

热门文章

  1. Flash Builder 4注册机下载地址
  2. JBDC数据库连接池技术(学习笔记)
  3. AMD推土机系列问世,8核CPU处理速度创世界记录
  4. 线性代数计算器C语言程序,新手作品:行列式计算C语言版
  5. Python Selenium 自动修改路由器WAN IP
  6. 兰州理工大c语言成绩,中国甘肃网:第三轮学科评估结果公布 兰州理工大16门学科上榜...
  7. Universal USB Installer 使用教程
  8. WebSphere9+IHS+Plugins安装部署
  9. HTML5:插入视频及在视频层面上执行的操作
  10. ZZ为了忘却的纪念------怀念我在HKUST-CSE的日子(完全版)