`
ahuango
  • 浏览: 55690 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Firefox 截图插件开发

 
阅读更多
在浏览网页的时候,看到好的内容都想保存下来,但是有些网页是禁止拷贝的,当然我们可以hack它以达到copy的目的,更快捷的方式则是截屏。于是想到了在Firefox下做一个截图软件,部分参考了screengrab这个插件。

这个插件用于我们一个网页兼容性测试结果比较和在GILD上存题使用,替GILD打个广告,技术人员可以在上面参与答题竞赛,可以拿到一些奖品的,如ipad、ipod等。

言归正传,开始插件开发

1. 老生长谈之插件目录结构

xxxcapture
   |
   | ---- chrome
             |--content
                    | -- overlay.xul
                    | -- options.xul
                    | -- gild.js
   | -- defaults
             | -- preferences
                    | -- pref.js
   | -- chrome.manifest
   | -- install.rdf     

install.rdf
这个是安装描述文件,
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <Description about="urn:mozilla:install-manifest">
        <em:id>dev@gild.com</em:id>
        <em:version>1.0</em:version> 
        <em:type>2</em:type>
       
        <em:targetApplication>
            <Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:minVersion>1.5</em:minVersion>
                <em:maxVersion>3.6.*</em:maxVersion>
            </Description>
        </em:targetApplication>
       
        <em:name>Gild Capture</em:name>
        <em:description>Gild Certification Screen capture</em:description>
        <em:creator>Jay</em:creator>
        <em:homepageURL>http://www.example.com/</em:homepageURL>
    </Description>            
</RDF>

这里主要的是<em:minVersion>和<em:maxVersion>表示所支持的Gecko的版本范围

  
chrome.manifest
这个文件里的内容主要包括了两个作用,
  • 定义文件的相对路径
  • 定义一些界面文件的位置

如:
content GildCapture chrome/content/
overlay chrome://browser/content/browser.xul chrome://GildCapture/content/overlay.xul

剩下的就是实现方面的了,主要是overlay.xul和gild.js

2. 定义插件菜单

界面重写部分在overlay.xul文件中,我们在status bar上定义一个弹出菜单

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://dev.webtest/content/overlay.css" type="text/css"?>

<overlay id="dev@gild.com" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">


<!-- Init Javascript
====================================================================== -->
<script src="gild.js"/>


<!-- Status Bar
======================================================================
- for more dynamic status bar, ref: adblockplus/overlay.xul
====================================================================== -->
<statusbar id="status-bar">

<statusbarpanel id="gild-status"
tooltiptext="Gild Capture"
insertafter="page-report-button,security-button"
context="gild-status-popup">
<image id="gild-status-img" src="chrome://GildCapture/content/paolo.png" style="width:16px;height:16px;cursor:pointer;"/>
</statusbarpanel>

</statusbar>


<!-- Popups -->
<popupset id="mainPopupSet">
<popup id="gild-status-popup" position="after_start">
<menuitem id="gild-menuitem-start" label="Begin" accesskey="b" oncommand="this.myCommand(event)"/>
<menuitem id="gild-menuitem-stop" label="End" accesskey="e" oncommand="this.myCommand(event)" />
<menuitem id="gild-menuitem-options" label="Options..." accesskey="o" oncommand="this.myCommand(event)"/>
<menuitem id="gild-menuitem-result" label="Show result" oncommand="this.myCommand(event)" />
</popup>
</popupset>

</overlay>




3.实现截图

截图部分有三个主要部分选取窗口区域,捕获图片和输出到文件。

选取窗口区域
此插件是截取整个document的内容所以会考虑到有滚动条的情况,并且考虑到有些document是按照quirks mode渲染的,此时其宽度和高度将从根元素上获得
getVisibleRegion:function() {
		var win = window.top.getBrowser().selectedBrowser.contentWindow;
		var htmlWin = win.content.window;
		var htmlDoc = win.document;
		var r = {};
		r.x = htmlWin.scrollX;
		r.y = htmlWin.scrollY;

		if(htmlDoc.compatMode == "CSS1Compat") {
			//standard mode
			r.width = htmlDoc.documentElement.clientWidth;
			r.height = htmlDoc.documentElement.clientHeight;
		} else {
			r.width = htmlDoc.body.clientWidth;
			r.height = htmlDoc.body.clientHeight;
		}
	
		return r;
	}


捕获图片

图片的获取是通过canvas这个元素,FF 从1.5就已经支持它了,虽然在HTML5中才公开支持。

var r = this.getScrollRegion();
		var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "html:canvas");
		canvas.width = r.width;
		canvas.height = r.height;
		canvas.style.width = canvas.style.maxwidth = r.width + 'px';
		canvas.style.height = canvas.style.maxheight = r.height + 'px';

		var context = canvas.getContext("2d");
		context.clearRect(r.x,r.y,r.width,r.height);
		context.save();

		context.drawWindow(window._content,r.x,r.y,r.width,r.height,"rgb(255,255,255)");

保存图片到文件
保存图片则是通过文件的一些I/O Api和nsWebBrowserPersist输出到文件,
var dir = this.getSaveFolder();
		dir.append(this.serial++ + ".jpg");
		dir.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE,0666);

		var f = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		f.initWithPath(dir.path);
		
		var io = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
		var source = io.newURI(canvas.toDataURL("image/jpeg","quality=60"),"UTF8",null);
		var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Components.interfaces.nsIWebBrowserPersist);
		persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
		persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
		persist.saveURI(source,null,null,null,null,f);

分享到:
评论
1 楼 sonichy 2015-04-07  
我最近正在研究firefox截图,你的现在已经不兼容37,而且代码太复杂,还能精简么?

相关推荐

Global site tag (gtag.js) - Google Analytics