Open abeet opened 5 years ago
在ZCMS中专题可视化制作,原来的截图用的是html2canvas,其原理是解析html和css,在Canvas上绘制截图,相当于实现了浏览器的css解析部分的功能,不但无法正确还实际的界面效果,绘制的的速度还很慢,甚至会因为脚本错误导致无法返回截图。 现在的思路是用C#在本地跑一个http服务器,并响应js请求对网页截屏,然后上传图像到远程服务器。
在baidu 里搜索“C#截图”找到一些文章 如 https://blog.csdn.net/weixin_36381867/article/details/79434143
为了写C#,找一下相关的文档 https://www.asp.net/get-started
查 .netcore的api手册,没有找到与http通讯有关的内容,在microsofe全站搜索“CopyFromScreen”找到了 https://docs.microsoft.com/zh-cn/dotnet/api/system.drawing.graphics.copyfromscreen?view=netframework-4.7.2#System_Drawing_Graphics_CopyFromScreen_System_Int32_System_Int32_System_Int32_System_Int32_System_Drawing_Size_ 看来 .net core里没有CopyFromScreen,.net framework里有 CopyFromScreen。 怎么办? 先尝试一下在.net core里用.net framework里的功能 在google里搜索“.net core Bitmap” 找到这个页面 https://stackoverflow.com/questions/40892189/net-core-and-system-drawing 大意是,.net core的TargetFramework 为 netcoreapp 它是跨平台的,没有包含操作系统的api如目录操作等。 .NET Framework 的 TargetFramework 为net46 它们是不能混用的。
所以我们要开始一个新的项目,基于.NET Framework的实现
先看文档 https://docs.microsoft.com/zh-cn/dotnet/framework/index 记下可能要参考的文档 https://docs.microsoft.com/zh-cn/dotnet/framework/network-programming/network-programming-samples 《网络编程示例》 https://docs.microsoft.com/en-us/dotnet/api/system.net.httplistener?redirectedfrom=MSDN&view=netframework-4.7.2 没想到.NET Framework开启一个http访问也挺简单的。。。
遇到“c# 未能找到类型或命名空间”的解决 找到右侧的“解决方案“1个项目””下的子目录“引用”,右键点击,“添加引用”,选择“.net”,活动鼠标,找到“System.Drawing”,选中它,点击确定。就OK了!
在git上搜索 “Graphics.FromImage BackgroundImage WindowState ShowInTaskbar FormBorderStyle” 找到截图功能参考代码 https://github.com/Horiatu/PrintScreen/blob/master/PrintScreen/CaptureForm.cs 支持按下alt键
https://github.com/sysr-q/xcap/blob/master/src/Snap.cs 有图片上传示例
https://github.com/fish-li/ClownFish.Tucao/blob/master/src/client/ClownFish.Tucao.WinClient/CaptureForm.cs
https://github.com/Dinokaiz2/AUTONOTE/blob/master/AUTONOTE/SnipForm.cs 中文注释
https://github.com/adzm/BusinessCats/blob/master/SnippingCat.cs
https://github.com/rayel/SinaWeiboClient/blob/master/WeiboClient/Forms/ScreenShot.cs
在github上搜索”new HttpListener HttpListenerContext HttpListenerRequest 200 route“ 和 ”new HttpListener HttpListenerContext HttpListenerRequest 200 routes“ ”new HttpListener HttpListenerContext HttpListenerRequest 200 router“ 找了一些实现HTTPServer的代码,选择最简短的几个类
https://github.com/MemoryPenguin/CodeSync2/blob/master/CodeSync2-Server/Network/HttpServer.cs https://github.com/klasbj/fsxrelay/blob/master/fsx_relay_console/HttpServer.cs https://github.com/ktos/BasicRestServer/blob/master/BasicRestServer.Netmf/BasicRestServer.cs
结合 https://github.com/Dinokaiz2/AUTONOTE/blob/93e60d91b9/AUTONOTE/SnipForm.cs 和 https://github.com/ktos/BasicRestServer/blob/master/BasicRestServer.Netmf/BasicRestServer.cs 实现了,访问 http://localhost:8080/capture?x=11&y=22&w=444&h=333 将主屏幕的特定位置载图的效果。
现在要定位浏览器所在的窗口进行截图,我设想浏览器所在窗口即鼠标所在窗口, 于是在github上搜索 ”AllScreens CopyFromScreen Cursor.Position“ 找到如下代码,来获取当前鼠标所在屏幕的办法 https://github.com/pj-martins/ScreenCapture/blob/master/CaptureHelper.cs
将之前实现的word中图片上传到服务器的部分逻辑移到这个c#程序里
js交互部分比较简单,就不写了。
c#实现网页截图就这么完成了,代码量还挺少,发布后不到20k,耶。
还可以改进的地方,滚动窗口截长图——现在zcms里专题的编辑区是限定在一个iframe里的,要找到这个iframe并滚动它可能有点麻烦,容后再实现。
总是截图失败,取到的鼠标位置总是0,0,取到的屏幕宽总是为1024*768, 在google上搜索“c# service Screen” 找到文章 https://stackoverflow.com/questions/4712532/why-does-print-screen-in-a-windows-service-return-a-black-image 原来出于安全考虑后台服务不允许读取屏幕。 只能把截屏程序另外写一个了。
查资料解决以下问题
所有问题解决后,仍然有问题还是获取不到真实屏幕,看来是另外一个问题了 搜索”服务 新进程 运行 Windows 7“——这个搜索词是在多次尝试后才得到的 发现文章 http://www.cnblogs.com/gnielee/archive/2010/04/08/session0-isolation-part2.html 再在github上搜索”CreateProcessAsUser“ 找到项目 https://github.com/murrayju/CreateProcessAsUser 把代码搬过来,又有几个问题
注意一下后台服务的 ApplicationData 目录在 C:\Users\abeet\AppData\Roaming\zving.com 而前台应用的 ApplicationData 目录在 C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming
牛逼 感觉泽元cms的比拓尔思的好用,功能强大点, 变成泽元长沙分公司老总了, 作者牛啊,从产品到前端到老总
目的
在ZCMS中专题可视化制作,原来的截图用的是html2canvas,其原理是解析html和css,在Canvas上绘制截图,相当于实现了浏览器的css解析部分的功能,不但无法正确还实际的界面效果,绘制的的速度还很慢,甚至会因为脚本错误导致无法返回截图。 现在的思路是用C#在本地跑一个http服务器,并响应js请求对网页截屏,然后上传图像到远程服务器。
实现过程
在baidu 里搜索“C#截图”找到一些文章
如 https://blog.csdn.net/weixin_36381867/article/details/79434143
为了写C#,找一下相关的文档 https://www.asp.net/get-started
查 .netcore的api手册,没有找到与http通讯有关的内容,在microsofe全站搜索“CopyFromScreen”找到了 https://docs.microsoft.com/zh-cn/dotnet/api/system.drawing.graphics.copyfromscreen?view=netframework-4.7.2#System_Drawing_Graphics_CopyFromScreen_System_Int32_System_Int32_System_Int32_System_Int32_System_Drawing_Size_
看来 .net core里没有CopyFromScreen,.net framework里有 CopyFromScreen。 怎么办? 先尝试一下在.net core里用.net framework里的功能 在google里搜索“.net core Bitmap” 找到这个页面 https://stackoverflow.com/questions/40892189/net-core-and-system-drawing 大意是,.net core的TargetFramework 为 netcoreapp 它是跨平台的,没有包含操作系统的api如目录操作等。 .NET Framework 的 TargetFramework 为net46 它们是不能混用的。
所以我们要开始一个新的项目,基于.NET Framework的实现
先看文档 https://docs.microsoft.com/zh-cn/dotnet/framework/index
记下可能要参考的文档
https://docs.microsoft.com/zh-cn/dotnet/framework/network-programming/network-programming-samples
《网络编程示例》
https://docs.microsoft.com/en-us/dotnet/api/system.net.httplistener?redirectedfrom=MSDN&view=netframework-4.7.2
没想到.NET Framework开启一个http访问也挺简单的。。。
在git上搜索 “Graphics.FromImage BackgroundImage WindowState ShowInTaskbar FormBorderStyle”
找到截图功能参考代码
https://github.com/Horiatu/PrintScreen/blob/master/PrintScreen/CaptureForm.cs
支持按下alt键
https://github.com/sysr-q/xcap/blob/master/src/Snap.cs
有图片上传示例
https://github.com/fish-li/ClownFish.Tucao/blob/master/src/client/ClownFish.Tucao.WinClient/CaptureForm.cs
https://github.com/Dinokaiz2/AUTONOTE/blob/master/AUTONOTE/SnipForm.cs
中文注释
https://github.com/adzm/BusinessCats/blob/master/SnippingCat.cs
https://github.com/rayel/SinaWeiboClient/blob/master/WeiboClient/Forms/ScreenShot.cs
在github上搜索”new HttpListener HttpListenerContext HttpListenerRequest 200 route“ 和 ”new HttpListener HttpListenerContext HttpListenerRequest 200 routes“ ”new HttpListener HttpListenerContext HttpListenerRequest 200 router“
找了一些实现HTTPServer的代码,选择最简短的几个类
https://github.com/MemoryPenguin/CodeSync2/blob/master/CodeSync2-Server/Network/HttpServer.cs
https://github.com/klasbj/fsxrelay/blob/master/fsx_relay_console/HttpServer.cs
https://github.com/ktos/BasicRestServer/blob/master/BasicRestServer.Netmf/BasicRestServer.cs
结合 https://github.com/Dinokaiz2/AUTONOTE/blob/93e60d91b9/AUTONOTE/SnipForm.cs
和 https://github.com/ktos/BasicRestServer/blob/master/BasicRestServer.Netmf/BasicRestServer.cs
实现了,访问 http://localhost:8080/capture?x=11&y=22&w=444&h=333 将主屏幕的特定位置载图的效果。
现在要定位浏览器所在的窗口进行截图,我设想浏览器所在窗口即鼠标所在窗口,
于是在github上搜索 ”AllScreens CopyFromScreen Cursor.Position“
找到如下代码,来获取当前鼠标所在屏幕的办法
https://github.com/pj-martins/ScreenCapture/blob/master/CaptureHelper.cs
将之前实现的word中图片上传到服务器的部分逻辑移到这个c#程序里
js交互部分比较简单,就不写了。
c#实现网页截图就这么完成了,代码量还挺少,发布后不到20k,耶。
还可以改进的地方,滚动窗口截长图——现在zcms里专题的编辑区是限定在一个iframe里的,要找到这个iframe并滚动它可能有点麻烦,容后再实现。
打包成服务后出现了一个大问题
总是截图失败,取到的鼠标位置总是0,0,取到的屏幕宽总是为1024*768, 在google上搜索“c# service Screen” 找到文章 https://stackoverflow.com/questions/4712532/why-does-print-screen-in-a-windows-service-return-a-black-image
原来出于安全考虑后台服务不允许读取屏幕。 只能把截屏程序另外写一个了。
查资料解决以下问题
所有问题解决后,仍然有问题还是获取不到真实屏幕,看来是另外一个问题了 搜索”服务 新进程 运行 Windows 7“——这个搜索词是在多次尝试后才得到的
发现文章 http://www.cnblogs.com/gnielee/archive/2010/04/08/session0-isolation-part2.html
再在github上搜索”CreateProcessAsUser“
找到项目 https://github.com/murrayju/CreateProcessAsUser
把代码搬过来,又有几个问题
查资料,并测试,后来发现,在以服务模式运行才能正常执行这个方法
注意一下后台服务的 ApplicationData 目录在 C:\Users\abeet\AppData\Roaming\zving.com 而前台应用的 ApplicationData 目录在 C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming