将帧从外部swf导出到Javascript

Nik*_*las 3 javascript flash actionscript actionscript-3

我试图从(任何)外部swf文件中捕获一个静止帧,通过使用我自己的flash影片作为代理加载它并将关于舞台的信息传递到javascript.我希望尽可能保持兼容性,所以我现在使用AS2/Flash 8.

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

trace(flash2canvasScreenshot.getPixel(w, h).toString(16));
Run Code Online (Sandbox Code Playgroud)

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

ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16));
Run Code Online (Sandbox Code Playgroud)

在已发表的电影中没有.

对于大型闪存(尺寸方面)电影,这种方法显然可能非常慢,因为它迭代每个像素.如果有人有任何更好的方法,请随意分享,但正如所说,我面临的问题是我在调试和发布方面得到了不同的结果,在发布时没有获取像素信息.

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);
Run Code Online (Sandbox Code Playgroud)

Geo*_*nza 10

您发布的代码段几乎没有问题:

  1. 就像乔伊所提到的那样,但从我的观点来看,那个突出的element变量是没有在任何地方定义的变量,所以要么是一个类型o,要么是你想要绘制一个 undefined对象.
  2. 您在加载完成后即刻绘制,但您加载的动画可能稍后开始.也许在加载完成后稍稍拍摄快照.
  3. 有一段时间没有触及as2并且不记得如何处理安全问题,但是如果你是swf正在从另一个域加载另一个swf,那么托管你正在加载的swf的域也应该有一个跨域. 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
}
Run Code Online (Sandbox Code Playgroud)

这是150x150快照的快速缩放预览: 预习

这是一个as3代码片段,用于说明安全沙箱处理问题:

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));
}
Run Code Online (Sandbox Code Playgroud)

HTH