背景
最近再做一个需求,需要对网页生成预览图,如下图
但是网页千千万,总不能一个个打开,截图吧;于是想着能不能使用代码来实现网页的截图。其实要实现这个功能,无非就是要么实现一个仿真浏览器,要么调用系统浏览器,再进行截图操作。
代码实现
1、启用线程Thread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
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 second while (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 bar var 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、截图操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
private static Bitmap CutImage(Bitmap source, Rectangle section) { // An empty bitmap which will hold the cropped image Bitmap 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); } |
完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public static string ScreenShotAndSaveAmazonS3( string account, string locale, Guid rule_ID, Guid template_ID) { //新的Template var 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; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
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 second while (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 bar var 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 image Bitmap 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# 页面截取为图片的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/lyl6796910/archive/2021/01/08/14250948.html