C#使用phantomjs 进行网页整页截屏
C#使用phantomjs 进行网页整页截屏
hantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器,这样访问网页就省去了浏览器的界面绘制所消耗的系统资源,比较适合用于网络测试等应用 。我只是调用了其中的一个截取网页的小功能,可以完美的解析网页的js和css 而且兼容html5,不过最新的1.5版本不支持flash,所以我采用了1.4的版本,能够得到完整的网页体验。
先看看执行的效率(4M电信,:30点测试): phantomjs的目录结构 dll挺多的 都是必须的 codecs里面包含编码信息 qcncodecs4.dll 这个是中文支持 里面还有韩文 日文和台湾繁体中文 这玩意必须有 要不然会出现乱码的。
imageformats目录里面是qgif4.dll和qjpeg4.dll两个dll 是用于图片转换的 默认png格式。 rasterize.js 就是官方写好的截屏的js代码
var page = require('webpage').create(), address, output, size; if (phantom.args.length < || phantom.args.length > ) { console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]'); console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"'); phantom.exit(); } else { address = phantom.args[]; output = phantom.args[]; page.viewportSize = { width: , height: }; if (phantom.args.length === && phantom.args[].substr(-) === ".pdf") { size = phantom.args[].split('*'); page.paperSize = size.length === ? { width: size[], height: size[], border: '0px' } : { format: phantom.args[], orientation: 'portrait', border: '1cm' }; } page.open(address, function (status) { if (status !== 'success') { console.log('Unable to load the address!'); } else { window.setTimeout(function () { page.render(output); phantom.exit(); }, ); } }); }
看这个js的意思貌似可以将pdf文件转换为图片文件,我没有测试。我调用的时候只是传了两个参数。
下面的就算调用的核心js代码 直接输出图像文件。
page.render(output);
在C#中调用这玩意的代码是:
private void GetImage(string url) { string links = url.IndexOf("http://") > - ? url : "http://" + url; #region 启动进程 Process p = new Process(); p.StartInfo.FileName = Environment.CurrentDirectory+"//phantomjs.exe"; p.StartInfo.WorkingDirectory = Environment.CurrentDirectory+"//pic//"; p.StartInfo.Arguments = string.Format("--ignore-ssl-errors=yes --load-plugins=yes " + Environment.CurrentDirectory + "//rasterize.js " + links + " "+url+".png"); p.StartInfo.CreateNoWindow = true; p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; if (!p.Start()) throw new Exception("无法Headless浏览器."); #endregion }
关键是这里
p.StartInfo.Arguments = string.Format("--ignore-ssl-errors=yes --load-plugins=yes " + Environment.CurrentDirectory + "//rasterize.js " + links + " "+url+".png");
--ignore-ssl-errors=yes 忽视加密的ssl连接错误
--load-plugins=yes 载入插件
上面的两参数可以不用 ,加上了是为了体验真实的网页体验效果,比如,不载入插件的话 flash就不会加载的。
Environment.CurrentDirectory + "//rasterize.js " 这里就是调用写好的js驱动代码,下面带上的参数是作用于这个js的。
links 访问的网址连接,最好加入http://。
"+url+".png 输出的图片 默认是png格式 当包含了上面 imageformats里面的dll的话 就可以输出jpg格式和gif格式的图片。 所有代码就这样子的,用起来很简单,就像在代码中调用cmd一样的。这样就很容易在不错的机子上进行多线程的批量截图而不影响任何操作,效率方面还很不错!
C#使用GDI+制作背景颜色淡入淡出效果的按钮
用过QQ2009的网友都知道QQ主面板的界面非常炫丽,特别好看,鼠标移上去还有淡入淡出的效果。那这样效果是怎么做出来的呢?其实不难,只要自定义一个用户控件的外怪就可以了,用到GDI+技术和时钟控件来操作…
首先我们在VS2008里面新建一个Windows窗体控件库的项目,系统会自动生成一个用户控件UserControl1.cs出来,我们就用默认的名字吧~~
本例子下载地址:http://files.cnblogs.com/mengxin523/自定义按钮控件.rar
程序所有代码如下: using System; using System.Data; using System.Drawing; using System.Collections; using System.Windows.Forms; using System.ComponentModel; using System.Drawing.Drawing2D; namespace MyButton { public partial class UserControl1 : UserControl { private bool calledbykey = false; private State mButtonState = State.None; //按钮的状态 private Timer mFadeIn = new Timer(); //淡入的时钟 private Timer mFadeOut = new Timer(); //淡出的时钟 private int mGlowAlpha = ; //透明度 private System.ComponentModel.Container components = null; public UserControl1() { InitializeComponent(); //一下几个语句是对控件进行设置和对GDI+进行优化 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); this.UpdateStyles(); this.BackColor = Color.Transparent; //设置控件背景色透明 mFadeIn.Interval = ; //淡入速度 mFadeOut.Interval = ; //淡出速度 } protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } private void InitializeComponent() { this.Name = "MySystemButton"; this.Size = new System.Drawing.Size(, ); this.Paint += new System.Windows.Forms.PaintEventHandler(this.VistaButton_Paint); this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyUp); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyDown); this.MouseEnter += new System.EventHandler(this.VistaButton_MouseEnter); this.MouseLeave += new System.EventHandler(this.VistaButton_MouseLeave); this.MouseUp += new MouseEventHandler(VistaButton_MouseUp); this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.VistaButton_MouseDown); this.GotFocus += new EventHandler(VistaButton_MouseEnter); this.LostFocus += new EventHandler(VistaButton_MouseLeave); this.mFadeIn.Tick += new EventHandler(mFadeIn_Tick); this.mFadeOut.Tick += new EventHandler(mFadeOut_Tick); this.Resize += new EventHandler(VistaButton_Resize); } enum State { None, Hover, Pressed }; /// <summary> /// 按钮的样式 /// </summary> public enum Style { /// <summary> /// Draw the button as normal /// </summary> Default, /// <summary> /// Only draw the background on mouse over. /// </summary> Flat }; /// <summary> /// 用于设置按钮的用处 /// </summary> public enum UseTo { Min, Close }; UseTo Ut = UseTo.Close; //默认作为关闭按钮 [Category("UseTo"), DefaultValue(UseTo.Close), Browsable(true), Description("设置按钮的用处")] public UseTo UT { get { return Ut; } set { Ut = value; this.Invalidate(); } } private string mText; /// <summary> /// 按钮上显示的文本 /// </summary> [Category("Text"), Description("按钮上显示的文本.")] public string ButtonText { get { return mText; } set { mText = value; this.Invalidate(); } } private Color mForeColor = Color.White; /// <summary> /// 文本颜色 /// </summary> [Category("Text"), Browsable(true), DefaultValue(typeof(Color), "White"), Description("文本颜色.")] public override Color ForeColor { get { return mForeColor; } set { mForeColor = value; this.Invalidate(); } } private ContentAlignment mTextAlign = ContentAlignment.MiddleCenter; /// <summary> /// 文本对齐方式 /// </summary> [Category("Text"), DefaultValue(typeof(ContentAlignment), "MiddleCenter")] public ContentAlignment TextAlign { get { return mTextAlign; } set { mTextAlign = value; this.Invalidate(); } } private Image mImage; /// <summary> 按钮上的图片 /// </summary> [Category("Image"), DefaultValue(null)] public Image Image { get { return mImage; } set { mImage = value; this.Invalidate(); } } private ContentAlignment mImageAlign = ContentAlignment.MiddleLeft; /// <summary> 按钮对齐方式 /// </summary> [Category("Image"), DefaultValue(typeof(ContentAlignment), "MiddleLeft")] public ContentAlignment ImageAlign
C#使用API屏蔽系统热键和任务管理器
最近做的一个winform类型的项目中需要屏蔽系统热键,在网上搜索了一下,基本上都是调用api来进行hook操作,下面的代码就可以完成功能
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WAT.PMS
{
    /// <summary>
    /// Description: Hook Helper类,可以屏蔽一些热键并屏蔽任务管理器
    /// Author: ZhangRongHua
    /// Create DateTime: 2009-6-19 20:21
    /// UpdateHistory:
    /// </summary>
    public class HookHelper
    {
        #region Delegates
        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
        #endregion
        #region 变量声明
        private HookProc KeyboardHookProcedure;
        private FileStream MyFs; // 用流来屏蔽ctrl alt delete
        private const byte LLKHF_ALTDOWN = 0x20;
        private const byte VK_CAPITAL = 0x14;
        private const byte VK_ESCAPE = 0x1B;
        private const byte VK_F4 = 0x73;
        private const byte VK_LCONTROL = 0xA2;
        private const byte VK_NUMLOCK = 0x90;
        private const byte VK_RCONTROL = 0xA3;
        private const byte VK_SHIFT = 0x10;
        private const byte VK_TAB = 0x09;
        public const int WH_KEYBOARD = ;
        private const int WH_KEYBOARD_LL = ;
        private const int WH_MOUSE = ;
        private const int WH_MOUSE_LL = ;
        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;
        private const int WM_LBUTTONDBLCLK = 0x203;
        private const int WM_LBUTTONDOWN = 0x201;
        private const int WM_LBUTTONUP = 0x202;
        private const int WM_MBUTTONDBLCLK = 0x209;
        private const int WM_MBUTTONDOWN = 0x207;
        private const int WM_MBUTTONUP = 0x208;
        private const int WM_MOUSEMOVE = 0x200;
        private const int WM_MOUSEWHEEL = 0x020A;
        private const int WM_RBUTTONDBLCLK = 0x206;
        private const int WM_RBUTTONDOWN = 0x204;
        private const int WM_RBUTTONUP = 0x205;
        private const int WM_SYSKEYDOWN = 0x104;
        private const int WM_SYSKEYUP = 0x105;
        private static int hKeyboardHook = ;
        #endregion
        #region 函数转换
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        //   卸载钩子  
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        //   继续下一个钩子  
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
        //   取得当前线程编号  
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern short GetKeyState(int vKey);
        #endregion
        #region 方法
        /// <summary>
        /// 钩子回调函数,在这里屏蔽热键。
        /// <remark> 
        /// Author:ZhangRongHua 
        /// Create DateTime: 2009-6-19 20:19
        /// Update History:     
        ///  </remark>
        /// </summary>
        /// <param name="nCode">The n code.</param>
        /// <param name="wParam">The w param.</param>
        /// <param name="lParam">The l param.</param>
        /// <returns></returns>
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            KeyMSG m = (KeyMSG) Marshal.PtrToStructure(lParam, typeof (KeyMSG));
            if (((Keys) m.vkCode == Keys.LWin) || ((Keys) m.vkCode == Keys.RWin) ||
                ((m.vkCode == VK_TAB) && ((m.flags & LLKHF_ALTDOWN) != )) ||
                ((m.vkCode == VK_ESCAPE) && ((m.flags & LLKHF_ALTDOWN) != )) ||
                ((m.vkCode == VK_F4) && ((m.flags & LLKHF_ALTDOWN) != )) ||
                (m.vkCode == VK_ESCAPE) && ((GetKeyState(VK_LCONTROL) & 0x8000) != ) ||
                (m.vkCode == VK_ESCAPE) && ((GetKeyState(VK_RCONTROL) & 0x8000) != )
                )
            {
                return ;
            }
            return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
        }
        /// <summary>
        /// 启动Hook,并用流屏蔽任务管理器
        /// <remark> 
        /// Author:ZhangRongHua 
        /// Create DateTime: 2009-6-19 20:20
        /// Update History:     
        ///  </remark>
        /// </summary>
        public void HookStart()
        {
            if (hKeyboardHook == )
            {
                //   创建HookProc实例  
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD,
                                                 KeyboardHookProcedure,
                                                 Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[]),
                                                 );
                //   如果设置钩子失败  
                if (hKeyboardHook == )
                {
                    HookStop();
                    //throw new Exception("SetWindowsHookEx   failedeeeeeeee.");
                }
                //用二进制流的方法打开任务管理器。而且不关闭流.这样任务管理器就打开不了
                MyFs = new FileStream(Environment.ExpandEnvironmentVariables("%windir%\\system32\\taskmgr.exe"),
                                      FileMode.Open);
                byte[] MyByte = new byte[(int) MyFs.Length];
                MyFs.Write(MyByte, , (int) MyFs.Length);
            }
        }
        /// <summary>
        /// 卸载hook,并关闭流,取消屏蔽任务管理器。
        /// <remark> 
        /// Author:ZhangRongHua 
        /// Create DateTime: 2009-6-19 20:21
        /// Update History:     
        ///  </remark>
        /// </summary>
        public void HookStop()
        {
            bool retKeyboard = true;
            if (hKeyboardHook != )
            {
                retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                hKeyboardHook = ;
            }
            if (null != MyFs)
            {
                MyFs.Close();
            }
            if (!(retKeyboard))
            {
                throw new Exception("UnhookWindowsHookEx     failedsssss.");
            }
        }
        #endregion
        #region Nested type: KeyMSG
        public struct KeyMSG
        {
            public int dwExtraInfo;
            public int flags;
            public int scanCode;
            public int time;
            public int vkCode;
        }
        #endregion
    }
}
PS:也可以通过将[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System] 下的DisableTaskmgr项的值设为"1”来屏蔽任务管理器。
 
C#操作Win32 API函数
摘要:这里介绍C#操作Win32 API函数,C#使用的类库是.Net框架为所有.Net程序开发提供的一个共有的类库——.Net FrameWork SDK。
    C#语言有很多值得学习的地方,这里我们主要介绍C#操作Win32 API函数,包括介绍section:INI文件中的段落名称等方面。
    C#操作Win32 API函数
    C#并不像C++,拥有属于自己的类库。C#使用的类库是.Net框架为所有.Net程序开发提供的一个共有的类库——.Net FrameWork SDK。虽然.Net FrameWork SDK内容十分庞大,功能也非常强大,但还不能面面俱到,至少它并没有提供直接操作INI文件所需要的相关的类。在本文中,C#操作Win32 API函数——WritePrivateProfileString()和GetPrivateProfileString()函数。这二个函数都位于“kernel32.dll”文件中。
    我们知道在C#中使用的类库都是托管代码(Managed Code)文件,而Win32的API函数所处的文件,都是非托管代码(Unmanaged Code)文件。这就导致了在C#中不可能直接使用这些非托管代码文件中的函数。好在.Net框架为了保持对下的兼容,也为了充分利用以前的资源,提出了互操作,通过互操作可以实现对Win32的API函数的调用。互操作不仅适用于Win32的API函数,还可以用来访问托管的COM对象。C#中对 Win32的API函数的互操作是通过命名空间“System.Runtime.InteropServices”中的“DllImport”特征类来实现的。它的主要作用是指示此属性化方法是作为非托管DLL的输出实现的。下面代码就是在C#利用命名空间 “System.Runtime.InteropServices”中的“DllImport”特征类申明上面二个Win32的API函数:
    C#操作Win32 API函数:
[ DllImport ( "kernel32" ) ]
private static extern long WritePrivateProfileString ( string
section ,
string key , string val , string filePath ) ;
    参数说明:section:INI文件中的段落;key:INI文件中的关键字;val:INI文件中关键字的数值;filePath:INI文件的完整的路径和名称。
    C#申明INI文件的读操作函数GetPrivateProfileString():
[ DllImport ( "kernel32" ) ]
private static extern int GetPrivateProfileString ( string section ,
string key , string def , StringBuilder retVal ,
int size , string filePath ) ;
    参数说明:section:INI文件中的段落名称;key:INI文件中的关键字;def:无法读取时候时候的缺省数值;retVal:读取数值;size:数值的大小;filePath:INI文件的完整路径和名称。
    下面是一个读写INI文件的类
public class INIClass
{
public string inipath;
[DllImport("kernel32")]
private static extern long WritePrivateProfileString
(string section,string key,string val,string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString
(string section,string key,string def,StringBuilder retVal,int size,string filePath);
///
/// 构造方法
///
/// 文件路径
public INIClass(string INIPath)
{
inipath = INIPath;
}
///
/// 写入INI文件
///
/// 项目名称(如 [TypeName] )
/// 键
/// 值
public void IniWriteValue(string Section,string Key,string Value)
{
WritePrivateProfileString(Section,Key,Value,this.inipath);
}
///
/// 读出INI文件
///
/// 项目名称(如 [TypeName] )
/// 键
public string IniReadValue(string Section,string Key)
{
StringBuilder temp = new StringBuilder();
int i = GetPrivateProfileString(Section,Key,"",temp,,this.inipath);
return temp.ToString();
}
///
/// 验证文件是否存在
///
/// 布尔值
public bool ExistINIFile()
{
return File.Exists(inipath);
}
}  
C#使用phantomjs 进行网页整页截屏的更多相关文章
- 用phantomjs 进行网页整页截屏
		写截取整个网页程序是一个做前台的哥们所托,要做一些漂亮的界面原形,参考一些不错的网站设计就帮他弄了个截屏的程序. phantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面 ... 
- js利用clipboardData在网页中实现截屏粘贴的功能
		目前仅有高版本的 Chrome 浏览器支持这样直接粘贴,其他浏览器目前为止还无法粘贴,不过火狐和ie11浏览器在可编辑的div中能够粘贴截图的图片也是base64位和Chrome利用clipboard ... 
- 利用 clipboardData 在网页中实现截屏粘贴的功能
		<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ... 
- 利用Chrome开发者工具功能进行网页整页截图的方法
		第一步:打开chrome开发者工具. 打开你想截图的网页,然后按下 F12(macOS 是 option + command + i)调出开发者工具,接着按「Ctrl + Shift + P」(mac ... 
- chrome开发者工具实现整站截屏
		我们经常要遇到将整个网站作为图片保存下来的情况,而windows系统自带的PrintScreen键只能保存当前屏幕的截图 在chrome浏览器中可以安装第三方的截图插件实现整站截图 今天我们要介绍的方 ... 
- chrome实现网页高清截屏(F12、shift+ctrl+p、capture)
		打开需要载屏的网页,在键盘上按下F12,出现以下界面 上图圈出的部分有可能会出现在浏览器下方,这并没有关系.此时按下 Ctrl + Shift + P(Mac 为 ⌘Command +⇧Shift + ... 
- Snipaste强大离线/在线截屏软件的下载、安装和使用
		步骤一: https://zh.snipaste.com/ ,去此官网下载. 步骤二:由于此是个绿色软件,直接解压即可. 步骤三:使用,见官网.ttps://zh.snipaste.com 按F1 ... 
- php结合phantomjs实现网页截屏、抓取js渲染的页面
		首先PhantomJS快速入门 PhantomJS是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, ... 
- 利用PhantomJS进行网页截屏,完美解决截取高度的问题
		关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS ... 
随机推荐
- js-url操作记录
			禁用回退&开启回退 // 必须声明方法 否则无法删除此监听器 function backCommon() { history.pushState(null, null, document.UR ... 
- 应用安全 - 代码审计 - JavaScript
			JavaScript Prototype污染 
- ES6新增特性
			ES6: ECMA 第六次改版 块级作用域: 凡是被{ }包裹住的代码都是块级作用域,除了对象 特点:会造成一个暂时性死区 新增声明变量的两种方式: let: a. ... 
- java Map与Bean相互转化
			import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector ... 
- python中json的基本使用
			一.json的概念 json是一种通用的数据类型 一般情况下接口返回的数据类型都是json 长得像字典,形式也是k-v{ } 其实json是字符串 字符串不能用key.value来取值,所以要先转换为 ... 
- uWSGI、uwsgi、WSGI、之间的关系,为什么要用nginx加uWSGI部署。
			WSGI 协议 WSGI:是一种协议规范,起到规范参数的作用,就像告诉公路一样,规定超车靠右行,速度不低于90km/h,等.但这一切都是对双方进行沟通,比如,重庆到武汉这条高速路,这儿重庆和武汉就各为 ... 
- python random模块导入及用法
			random是程序随机数,很多地方用到,验证码,图片上传的图片名称等,下面说说python random模块导入及用法 1,模块导入 import random 2,random用法 random.r ... 
- Oracle DBA_EXTENTS视图 与 DBA_SEGMENTS视图
			DBA_EXTENTS describes the extents comprising the segments in all tablespaces in the database. Note ... 
- Spring、Spring MVC、Struts2、、优缺点整理(转)
			Spring 及其优点 大部分项目都少不了spring的身影,为什么大家对他如此青睐,而且对他的追捧丝毫没有减退之势呢 Spring是什么: Spring是一个轻量级的DI和AOP容器框架. 说它轻量 ... 
- Linux环境下安装Django和Python
			1 下载前准备操作:安装相关的依赖库(工具包) yum install gcc patch libffi-devel python-devel zlib-devel bzip2-devel ... 
