2011-08-11 61 views
3

我想从一个(任何)外部swf文件捕获一个静帧,通过使用我自己的Flash电影作为代理来加载它并将有关舞台的信息放到JavaScript上。我想尽可能保持它的兼容性,所以我现在就使用AS2/Flash 8。从外部swf导出框架到Javascript

该脚本正常工作在Flash调试,即

trace(flash2canvasScreenshot.getPixel(w, h).toString(16)); 

返回正确的像素颜色,其中为:

ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16)); 

在发布的影片没有。

对于大型闪存(尺寸明智)的电影,这种方法显然会很慢,因为它会迭代每个像素。如果有人有更好的方法,可以随意分享,但正如我所说的,我面临的问题是,我在调试和发布时获得了不同的结果,并且在发布时不会获取像素信息。

import flash.display.BitmapData; 
import flash.external.*; 

var myLoader:MovieClipLoader = new MovieClipLoader(); 
var mclListener:Object = new Object(); 

mclListener.onLoadInit = function(target_mc:MovieClip) 
{ 

     var stageW = Stage.width; 
     var flash2canvasScreenshot:BitmapData = new BitmapData(stageW, Stage.height, false, 0x00000000); 
     var pixels:Array = new Array(); 
     flash2canvasScreenshot.draw(element); 

     for (w = 0; w <= stageW; w++) 
     { 
      trace(flash2canvasScreenshot.getPixel(w, h).toString(16)); // this gives correct color value for the pixels in the debugger 
      ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16)); // this just returns the bitmap default color, 0 in this case. 
      /* 
      for (h = 0; h <= Stage.height; h++) 
      { 
       var pixel = flash2canvasScreenshot.getPixel(w, h).toString(16); 
       pixels.push(pixel); 
      } 
      */ 
     } 

     //ExternalInterface.call("sendToJS",pixels.toString());*/ 



}; 


myLoader.addListener(mclListener); 

myLoader.loadClip("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf", 0); 
//myLoader.loadClip("https://s.ytimg.com/yt/swfbin/watch_as3-vflJjAza6.swf", 0); 

//myLoader.loadClip(_level0.flash2canvasurl, _root.mc); 
+0

你试过像'ExternalInterface.call(“sendToJS”,“42”);',以确保您的JS正在显示数据正确吗? – kolufild

+0

@kolufild是的,尝试了类似的东西,它正在接收数据。 – Niklas

+0

如果这是所有的代码,那么'h'是'undefined'。 – Joe

回答

10

有与您发布的片断几个问题:

  1. 像一个乔伊提及,但是从我的 的观点代表了一个是没有定义的变量element 任何地方,因此,无论是o型,还是试图绘制一个 undefined对象。
  2. 加载完成后即刻绘制,但您加载的动画可能稍后开始。也许在加载完成后拍快照。
  3. 有一段时间没有触及as2,不记得安全问题是如何处理的,但是如果你是swf从另一个域加载另一个swf,那么托管你正在加载的swf的域也应该有一个crossdomain.xml策略文件,允许您访问加载的swf的内容。如果你只是从另一个域加载和显示一个SWF,那很好。但是,如果您尝试使用BitmapData绘制swf,实际上您尝试从该swf的内容访问像素数据,因此您需要权限。如果您无法控制跨域策略文件,则可能需要使用服务器端脚本来将文件复制/代理到可授予您加载的swf访问权限的域。

这是你的代码段的一个简化版本的作品(没有外部接口/像素值部分):

var myLoader:MovieClipLoader = new MovieClipLoader(); 
var mclListener:Object = new Object(); 
mclListener.onLoadInit = function(target_mc:MovieClip) 
{ 
    var pixels:Array = new Array(); 
    setTimeout(takeSnapshot,2000,target_mc); 
} 

myLoader.addListener(mclListener); 
myLoader.loadClip("http://www.bbc.co.uk/science/humanbody/sleep/sheep/reaction_version5.swf",1); 
//myLoader.loadClip("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf", 1); 
//myLoader.loadClip("https://s.ytimg.com/yt/swfbin/watch_as3-vflJjAza6.swf", 0); 

function takeSnapshot(target:MovieClip):Void { 
    var flash2canvasScreenshot:BitmapData = new BitmapData(150, 150, false, 0x00000000);//tiny sample 
    flash2canvasScreenshot.draw(target); 
    _level1._alpha = 20;//fade the loaded content 
    _level0.attachBitmap(flash2canvasScreenshot,0);//show the snapshop. sorry about using _root 
} 

这里是150×150扣的快速缩放预览: preview

这里的as3 snippet来说明安全沙箱处理问题:

var swf:Loader = new Loader(); 
swf.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete); 
swf.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,loaderSecurityError); 
swf.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loaderIOError); 
swf.load(new URLRequest("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf"),new LoaderContext(true)); 

function loaderComplete(event:Event):void{ 
    setTimeout(takeSWFSnapshot,2000); 
} 
function loaderSecurityError(event:SecurityErrorEvent):void { 
    trace('caught security error',event.errorID,event.text); 
} 
function loaderIOError(event:IOErrorEvent):void{ 
    trace('caught I/O error',event.errorID,event.text,'\tattempting to load\t',swf.contentLoaderInfo.url); 
} 
function takeSWFSnapshot():void{ 
    var clone:BitmapData = new BitmapData(swf.content.width,swf.content.height,false,0); 
    try{ 
     clone.draw(swf.content); 
    }catch(e:SecurityError){ 
     trace(e.name,e.message,e.getStackTrace()); 
    } 
    addChild(new Bitmap(clone)); 
} 

HTH

2

我的这种做法是:

- 使用AS3的原因lukevanin评论:

只要记住,AS3可以加载一个AS2 SWF,而是一个AS2 SWF不能加载 的AS3 SWF,让您真正实现更大的兼容性(与你的 内容),如果你发布AS3

- 使用一个代理文件,以获取swf文件绕过沙盒中提琴重刑的问题(尽管如果SWF文件加载外部资源,并使用相对路径它可能会有点更复杂)

-Take帧的快照使用base64(见乔治Profenza的解决方案)

-Encode图像和将该**发送到JS method,然后解码以获取图像。

**我敢肯定,没有大小限制...