2011-08-11 43 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,然後解碼以獲取圖像。

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