在Flashplayer中显示PDF文件, SWFTools怎么用

目前在百度文档和另外一个什么在线文档中见过这个做法,在美国的box网站也见过。


在网址:http://www.swftools.org/download.html(或http://wiki.swftools.org/wiki/Main_Page)下载SWFTools的最新版的exe安装文件,然后安装到Windows。


swftools-inst-dir


现在,本地已经有pdf2swf.exe了,在cmd窗口中使用它:



C:\Program Files\SWFTools>pdf2swf D:\KONICA\displayPDF\Q_CRCC_0123.pdf -o D:\KONICA\displayPDF\Q_CRCC_0123.swf


pdf-2-swf-in-cmd


创建的SWF文件,看起来与原版的PDF没有什么不同:


converted-swf



28th June 2012增補:


現在再來看看如何將一個swf的第一幀輸出為一個圖像:


swfrender-command


SWFTools這套工具並非對所有的SWF都有效,因為SWF裏面可能包含actionscript,而actionscript可能會通過網絡訪問其他域名下的資源,並且同時,所有運行SWF的環境都會應用安全沙箱的規則來限制actionscript對於外界的訪問,所以在SWF里的代碼要訪問網絡才能正常呈現的情況下,SWFTools并不能如我們期望的那樣解決問題。而如果画面的内容是主要通过actionscript绘制的,那么不能期待它正常工作


13rd Dec 2012增補:

不过,我刚刚用swfrender将swftool从pdf转制出来的swf的画面输出为png,是成功的。


C:\Program Files\SWFTools>swfrender Q_CRCC_0213.swf -o C:\sample.png


18th Dec 2012增補:

现在又出现一个新问题,当我真正尝试将转制出来的SWF加载至我的Flash里播放时,我发现一个问题,就是被加载进来的SWF的类型是AVM1Flash影片。我们先假设文档类的内容如下:

package  {
	
	import flash.display.MovieClip;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.net.URLRequest;
	
	import flash.display.AVM1Movie;
	
	public class main extends MovieClip
	{
		private var _ldr:Loader;
		
		
		public function main() 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, this.addedToStageHandler);
		}
		
		
		private function addedToStageHandler($e:Event):void
		{
			this._ldr = new Loader();
			this._ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, this.loadedHandler);
			var $req:URLRequest = new URLRequest("iso.swf");
			this._ldr.load($req);
		}
		
		
		private function loadedHandler($e:Event):void
		{
			trace($e.target.content);
			var $dd:AVM1Movie = $e.target.content as AVM1Movie;
			this.addChild($dd:);
		}

	}
	
}


我们将会看到, trace($e.target.content) 输出的内容为: [object AVM1Movie]。而且我们同时也得到一个异常:

ArgumentError: Error #2180: 在 AVM1 內容已載入至 AVM2 (AS3) 內容的情況下,將 AVM1 內容 (AS1 或 AS2) 移動至 displayList 的不同部分是不合法的。


假如这个时候,我们想要解决的问题仅仅是显示这个SWF的问题的话,那么可以在加载完成事件触发以前,就把Loader对象添加到 displayList 中。这样,上述写法就变成:

package  {
	
	import flash.display.MovieClip;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.net.URLRequest;
	
	import flash.display.AVM1Movie;
	
	public class main extends MovieClip
	{
		private var _ldr:Loader;
		
		
		public function main() 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, this.addedToStageHandler);
		}
		
		
		private function addedToStageHandler($e:Event):void
		{
			this._ldr = new Loader();
			this._ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, this.loadedHandler);
			var $req:URLRequest = new URLRequest("iso.swf");
			this._ldr.load($req);
			this.addChild(_ldr);
		}
		
		
		private function loadedHandler($e:Event):void
		{
			trace($e.target.content);
			var $dd:AVM1Movie = $e.target.content as AVM1Movie;
		}

	}
	
}


然而这个办法的坏处是很显然的,你无法进一步操作这个加载进来的AVM1对象。于是进一步的搜索令我寻找到一个称为ForcibleLoader的工具类,它可以将AVM1转换为MovieClip。示例代码可以点此下载

ForcibleLoader的使用方法为:

package  {
	
	import flash.display.MovieClip;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.net.URLRequest;
	
	import flash.display.AVM1Movie;
	
	public class main extends MovieClip
	{
		private var _ldr:Loader;
		private var _fLoader:ForcibleLoader;
		private var _mc:MovieClip ;
		
		
		public function main() 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, this.addedToStageHandler);
		}
		
		
		private function addedToStageHandler($e:Event):void
		{
			this._ldr = new Loader();
			this._fLoader = new ForcibleLoader(_ldr)
			this._fLoader.load(new URLRequest('iso.swf'));
			this.addChild(_ldr);
			this.addEventListener(Event.ENTER_FRAME, this.onloadFunction);
		}
		
		
		private function onloadFunction(e:Event):void 
		{
			if (this._ldr.content != null) 
			{
				this.removeEventListener(Event.ENTER_FRAME, onloadFunction);
				this._mc = this._ldr.content as MovieClip;
				//this._mc.addFrameScript(12, loop);
				trace(this._mc.totalFrames);
				this._mc.gotoAndStop(1);
			}
		}
		
	}
	
}



18th Dec 2012增補:

之所以会坚持以为通过在AS加载AVM1的swf时,寻找解决方法,是因为受到一篇文章的误导:

PDF2SWF : Auto conversion from PDF to SWF


这个印度阿三在里面确定无疑地说SWFTools不能生成AVM2影片剪辑。不过这篇文章写于2009年。后来我在SWFTools的官网上面找到链接:

How do I create a AVM2 compatible SWF?


于是我尝试了使用新的命令来创建SWF(注意:其中insertstop的结果将使SWF的每一帧都有stop()指令,否则,SWF将会自动在逐个帧之间循环播放,而帧频被设定为0.25,即每帧停留4秒):

C:\Program Files\SWFTools>pdf2swf -T9 -s insertstop ISO27001.pdf -o xxx.swf


cmd-with-version-shot




现在使用最初的文档类的写法加载这个新生成的SWF:

package  {
	
	import flash.display.MovieClip;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.net.URLRequest;
	
	public class main extends MovieClip
	{
		private var _ldr:Loader;
		
		public function main() 
		{
			this.addEventListener(Event.ADDED_TO_STAGE, this.addedToStageHandler);
		}
		
		
		private function addedToStageHandler($e:Event):void
		{
			_ldr = new Loader();
			_ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, this.loadedHandler);
			var $req:URLRequest = new URLRequest("t9.swf");
			_ldr.load($req);
		}
		
		
		private function loadedHandler($e:Event):void
		{
			trace($e.target.content);
			var $mc:MovieClip = $e.target.content as MovieClip;
			addChild($mc);
			trace($mc.totalFrames);
			$mc.gotoAndStop(5);
		}
		
	}
	
}


其中 trace($e.target.content) 得到的第一行输出为:

[object MainTimeline_9549329e]


另外,在通过windows上面的GUI版本的SWFTools可以创建带有阅览器的SWF,但是我并未能够成功用命令行创建带有viewer的SWF文件。

with-viewer


Viewer可以自定义,详情参见:How do I create my own viewer?


19th Dec 2012增補:

根据上面链接中的内容,做了如下尝试:

C:\Program Files\SWFTools>swfcombine -o ff.swf rfx8.swf viewport=sss.swf


viewport后面的swf即是之前从pdf转制的swf。当然,需要注意,两个被合并的swf需要版本相同。不然会得到警告:

Warning: File contains both flash 8 and flash 9 actionscript


可是现在的问题仍然是,如何在转制的时候就一起合并。

在之前的实验中已经发现,viewer的swf需要与pdf2swf.exe在同一路径下。所以在这个前提下,下面的命令是会成功运行并且得到期望结果的:

C:\Program Files\SWFTools>pdf2swf -B rfx8.swf ISO27001.pdf -o 19th.swf


但从执行过程的输出来看,其实pdf2swf自动调用了swfcombine:

C:\Program Files\SWFTools>pdf2swf -B rfx8.swf ISO27001.pdf -o 19th.swf
NOTICE  processing PDF page 1 (841x595:0:0)
NOTICE  File contains jpeg pictures
NOTICE  processing PDF page 2 (841x595:0:0)
NOTICE  processing PDF page 3 (841x595:0:0)
NOTICE  processing PDF page 4 (841x595:0:0)
NOTICE  processing PDF page 5 (841x595:0:0)
NOTICE  processing PDF page 6 (841x595:0:0)
NOTICE  processing PDF page 7 (841x595:0:0)
NOTICE  processing PDF page 8 (841x595:0:0)
NOTICE  processing PDF page 9 (841x595:0:0)
NOTICE  processing PDF page 10 (841x595:0:0)
NOTICE  processing PDF page 11 (841x595:0:0)
NOTICE  processing PDF page 12 (841x595:0:0)
NOTICE  processing PDF page 13 (841x595:0:0)
NOTICE  processing PDF page 14 (841x595:0:0)
NOTICE  processing PDF page 15 (841x595:0:0)
NOTICE  processing PDF page 16 (841x595:0:0)
NOTICE  processing PDF page 17 (841x595:0:0)
NOTICE  processing PDF page 18 (841x595:0:0)
NOTICE  processing PDF page 19 (841x595:0:0)
NOTICE  processing PDF page 20 (841x595:0:0)
NOTICE  processing PDF page 21 (841x595:0:0)
NOTICE  processing PDF page 22 (841x595:0:0)
NOTICE  Writing SWF file 19th.swf
swfcombine  -X 841 -Y 595 "rfx8.swf" viewport="19th.swf" -o "19th.swf"


现在的问题是如何自制一个flash 9版本的viewer。过程如下,首先stage的尺寸是600x800;创建三个MovieClip元件,其子内容皆为在Flash Pro CS5.5中绘制的Graphic,将三者拖放到stage中:

viewer-design


三个元件的名称为:prev,next,viewport。


第一帧代码层上as代码如下:

import flash.events.MouseEvent;

prev.addEventListener(MouseEvent.MOUSE_DOWN, onPrev);
next.addEventListener(MouseEvent.MOUSE_DOWN, onNext);

function onPrev($e:MouseEvent):void
{
	viewport.prevFrame();
}

function onNext($e:MouseEvent):void
{
	viewport.nextFrame();
}

viewport.gotoAndStop(1);


测试运行,生成一个名为viewer.swf的flash文件。将它复制到SWFTools的路径下,重新执行命令。

C:\Program Files\SWFTools>pdf2swf -T9 -s insertstop -B viewer.swf ISO27001.pdf -o 19th-2.swf
NOTICE  processing PDF page 1 (841x595:0:0)
NOTICE  File contains jpeg pictures
NOTICE  processing PDF page 2 (841x595:0:0)
NOTICE  processing PDF page 3 (841x595:0:0)
NOTICE  processing PDF page 4 (841x595:0:0)
NOTICE  processing PDF page 5 (841x595:0:0)
NOTICE  processing PDF page 6 (841x595:0:0)
NOTICE  processing PDF page 7 (841x595:0:0)
NOTICE  processing PDF page 8 (841x595:0:0)
NOTICE  processing PDF page 9 (841x595:0:0)
NOTICE  processing PDF page 10 (841x595:0:0)
NOTICE  processing PDF page 11 (841x595:0:0)
NOTICE  processing PDF page 12 (841x595:0:0)
NOTICE  processing PDF page 13 (841x595:0:0)
NOTICE  processing PDF page 14 (841x595:0:0)
NOTICE  processing PDF page 15 (841x595:0:0)
NOTICE  processing PDF page 16 (841x595:0:0)
NOTICE  processing PDF page 17 (841x595:0:0)
NOTICE  processing PDF page 18 (841x595:0:0)
NOTICE  processing PDF page 19 (841x595:0:0)
NOTICE  processing PDF page 20 (841x595:0:0)
NOTICE  processing PDF page 21 (841x595:0:0)
NOTICE  processing PDF page 22 (841x595:0:0)
NOTICE  Writing SWF file 19th-2.swf
swfcombine  -X 841 -Y 595 "viewer.swf" viewport="19th-2.swf" -o "19th-2.swf"


实际上有一些地方需要注意,我将两个黄色翻页按钮摆放的Y位置是511,因为通过pdf2swf生成的SWF的高是按照pdf中的高度来设定的,就是提示中的595,而之后当呼叫swfcombine时这个数字作为参数被传入,结果,与viewer合成后的swf的高就变成了595了。现在的问题是,如何在pdf2swf中就指定这个高度,来调整输出的swf的高度,这样就可以令按钮不必遮住pdf的内容。

printed-swf


现在,这个新生成的swf是flash 9的版本,同时又具有了viewer,我们再来看看把它加载进一个Flash之后,得到的是个什么东东:

trace($mc.numChildren);	// 3
var $obj1:* = $mc.getChildAt(0);	// MovieClip, viewport
var $obj2:* = $mc.getChildAt(1);	// MovieClip, prev
var $obj3:* = $mc.getChildAt(2);	// MovieClip, next


这个结构与当初创建viewer时的结构是一样的,参见上面的截图。





相关文档:


http://www.swftools.org/pdf2swf.html (download)

http://wiki.swftools.org/wiki/Main_Page (document)



Refs:

http://activeden.net/forums/thread/open-pdf-with-as3/31867

http://alivepdf.bytearray.org/

http://www.swftools.org/

http://en.wikipedia.org/wiki/FlashPaper

http://163.32.219.6/blog/u882061/eeee/2009/12/30/1530

http://ithelp.ithome.com.tw/question/10040767



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值