C#使用phantomjs 进行网页整页截屏

hantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器,这样访问网页就省去了浏览器的界面绘制所消耗的系统资源,比较适合用于网络测试等应用 。我只是调用了其中的一个截取网页的小功能,可以完美的解析网页的js和css 而且兼容html5,不过最新的1.5版本不支持flash,所以我采用了1.4的版本,能够得到完整的网页体验。
先看看执行的效率(4M电信,22: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 < 2 || phantom.args.length > 3) {

    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[0];

    output = phantom.args[1];

    page.viewportSize = { width: 600, height: 600 };

    if (phantom.args.length === 3 && phantom.args[1].substr(-4) === ".pdf") {

        size = phantom.args[2].split(‘*‘);

        page.paperSize = size.length === 2 ? { width: size[0], height: size[1], border: ‘0px‘ }

                                           : { format: phantom.args[2], 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();

            }, 200);

        }

    });

}
看这个js的意思貌似可以将pdf文件转换为图片文件,我没有测试。我调用的时候只是传了两个参数。
下面的就算调用的核心js代码 直接输出图像文件。
page.render(output);
在C#中调用这玩意的代码是:
private void GetImage(string url) {

            string links = url.IndexOf("http://") > -1 ? 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 = 0;        //透明度

        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 = 20;   //淡入速度

            mFadeOut.Interval = 20;   //淡出速度

        }

        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(100, 32);

            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 = 13;

        private const int WH_KEYBOARD_LL = 13;

        private const int WH_MOUSE = 7;

        private const int WH_MOUSE_LL = 14;

        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 = 0;

        #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) != 0)) ||

                ((m.vkCode == VK_ESCAPE) && ((m.flags & LLKHF_ALTDOWN) != 0)) ||

                ((m.vkCode == VK_F4) && ((m.flags & LLKHF_ALTDOWN) != 0)) ||

                (m.vkCode == VK_ESCAPE) && ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) ||

                (m.vkCode == VK_ESCAPE) && ((GetKeyState(VK_RCONTROL) & 0x8000) != 0)

                )

            {

                return 1;

            }

            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 == 0)

            {

                //   创建HookProc实例  

                KeyboardHookProcedure = new HookProc(KeyboardHookProc);

                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD,

                                                 KeyboardHookProcedure,

                                                 Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),

                                                 0);

                //   如果设置钩子失败  

                if (hKeyboardHook == 0)

                {

                    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, 0, (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 != 0)

            {

                retKeyboard = UnhookWindowsHookEx(hKeyboardHook);

                hKeyboardHook = 0;

            }

            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(500);
int i = GetPrivateProfileString(Section,Key,"",temp,500,this.inipath);
return temp.ToString();
}
///
/// 验证文件是否存在
///
/// 布尔值
public bool ExistINIFile()
{
return File.Exists(inipath);
}
}  

原文地址:https://www.cnblogs.com/blogpro/p/11458464.html

时间: 2024-11-08 01:12:06

C#使用phantomjs 进行网页整页截屏的相关文章

用phantomjs 进行网页整页截屏

写截取整个网页程序是一个做前台的哥们所托,要做一些漂亮的界面原形,参考一些不错的网站设计就帮他弄了个截屏的程序. phantomjs   是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器,这样访问网页就省去了浏览器的界面绘制所消耗的系统资源,比较适合用于网络测试等应用 .我只是调用了其中的一个截取网页的小功能,可以完美的解析网页的js和css 而且兼容html5,不过最新的1.5版本不支持flash,所以我采用了1.4的版本,能够得到完整的网页体验. 先看看执行的效率(4M

【MFC】截图编辑插件技术总结(4):IE下网页整页截屏

现在大部分浏览器都已经实现了网页截图的功能,我要说的与这种情况稍有不同,浏览器是从内部获取,而因为我是ActiveX插件,需要从外部获取网页的document.但是,实现的思路基本一致,就是将Webbrowser放大到足够大,使滚动条不出现,然后调用IViewObject接口的Draw方法实现整页的截图.下面先给出代码实现,再对代码进行分析. 1 POINT pnt; 2 3 RECT rc; 4 5 HWND DeskHwnd = ::GetDesktopWindow(); //取得桌面句柄

js利用clipboardData在网页中实现截屏粘贴的功能

目前仅有高版本的 Chrome 浏览器支持这样直接粘贴,其他浏览器目前为止还无法粘贴,不过火狐和ie11浏览器在可编辑的div中能够粘贴截图的图片也是base64位和Chrome利用clipboardData的效果是一样的,只是在火狐和ie11浏览器中目前还无法实现类似用clipboardData直接获取图片的base64数据,它是自带的直接进去img数据 完整实例: <!DOCTYPE HTML><html lang="en-US"><head>&

phantomjs介绍-(js网页截屏、javascript网页解析渲染工具)

phantomjs介绍-(js网页截屏.javascript网页解析渲染工具) phantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器,这样访问网页就省去了浏览器的界面绘制所消耗的系统资源,比较适合用于网络测试等应用 .利用这个工具,我们可以轻松的搭建一个接口用于获取我们想要的url的整页截屏. PhantomJS is a headless WebKit with JavaScript API. It has fast and native support

Snipaste强大离线/在线截屏软件的下载、安装和使用

步骤一: https://zh.snipaste.com/  ,去此官网下载. 步骤二:由于此是个绿色软件,直接解压即可. 步骤三:使用,见官网.ttps://zh.snipaste.com  按F1开始截屏 感谢下面哥的精彩微信文章 http://mp.weixin.qq.com/s?__biz=MzIwNzYwODYwMw==&mid=2247483903&idx=1&sn=02121fe920320bbe7b2fae012a18e70a&chksm=970e8f8ba

Java实现网页截屏功能(基于phantomJs)

公司最近有个需求:把用户第一次的测量身体信息和最近一次测量信息进行对比,并且需要把对比的数据截成图片可以发给用户(需要在不打开网页的情况下实时对网页进行截图然后保存到服务器上,返回图片地址),通过网上的一些文章可以发现有以下几种实现方式:参考文章https://blog.csdn.net/wanglq0086/article/details/60761614 Robot 利用JNI,调用第三方C/C++组件 DJNativeSwing组件 利用html2canvas 利用html2image p

网页html截屏转图片(二)PhantomJS

关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG.PhantomJS可以用于页面自动化,网络监测,网页截屏,以及无界面测试等. 我们还可以用它来做爬虫哦,大家知道,网页上有些数据是通过执行js渲染出来的,这样的话爬虫去抓取数据的时候就会很麻烦,PhantomJS自带WebKit内核,我们可以利用Ph

Html5 实现网页截屏 页面生成图片(图文)

html2canvas通过获取页面的DOM和元素的样式信息,并将其渲染成canvas图片,从而实现给页面截图的功能. 因为每个浏览器渲染页面的方式都不尽相同,所以生成的图片也不太一样. 环境要求: jQuery兼容性: Firefox 3.5+, Chrome, Opera, IE9 官网主页: http://html2canvas.hertzen.com/ 测试生成的图片效果 有些元素的样式没有完全展示出来 1 <html> 2 <head> 3 <meta name=&q

nodejs+phantomjs+七牛 实现截屏操作并上传七牛存储

近来研究了下phantomjs,只是初涉,还谈不上深入研究,首先介绍下什么是phantomjs. 官网上的介绍是:”PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.”翻译过来就是:”PhantomJS