【问题标题】:Alternative to bitmapdata for snapshotting?用于快照的位图数据的替代方案?
【发布时间】:2025-12-01 19:35:01
【问题描述】:

我目前正在通过 as3 加载远程 swf(使用域策略允许来自该域的所有内容 - 策略文件不能由我自己更改),我想对其进行快照。问题是我加载的主 swf 正在从另一个没有启用“允许所有”策略的域加载子 swf。这使得快照功能称为“沙盒安全”错误。我想知道是否有位图数据绘制功能的替代方案仍然可以拍摄“快照”而不会与沙箱安全性冲突。

提前致谢。

【问题讨论】:

    标签: flash actionscript-3


    【解决方案1】:

    如果允许您从相关域加载数据,请执行以下操作:

    1. 使用 URLLoader 和 URLLoaderDataFormat.BINARY 将 swf 作为二进制数据加载
    2. 使用 Loader 和 loadBytes() 将二进制内容加载到显示对象中

    之后,您应该能够draw() 该 swf 的内容。

    编辑此技术的示例。

    只需将以下代码复制并粘贴到空白 fla 中,编译生成的 swf 并将其放在 http 上的某个位置(在本地测试时,两个 draw() 调用都会成功,因此您不会看到差异)。

    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.events.Event;
    import flash.utils.ByteArray;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.system.Security;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.text.TextField;
    import flash.display.StageScaleMode;
    
    var onBinaryComplete:Function = function (event:Event) : void
    {
        trace("onBinaryComplete()");
        var loader:URLLoader = event.target as URLLoader;
        var bytes:ByteArray = loader.data as ByteArray;
        trace(bytes.length+" bytes");
        bytesLoader.loadBytes(bytes);
    }
    
    var onBytesComplete:Function = function (event:Event) : void
    {
        trace("onBytesComplete()");
        var info:LoaderInfo = event.target as LoaderInfo;
        var bmp:BitmapData = new BitmapData(300, 300, true, 0x8000FF00);
        // this will not fail, you'll see an image
        bmp.draw(info.content);
        var bitmap = new Bitmap(bmp);
        bitmap.x += 100;
        bitmap.y += 100;
        stage.addChild(bitmap); 
    }
    
    var onDirectLoadComplete:Function = function (event:Event) : void
    {
        trace("onDirectLoadComplete()");
        var bmp:BitmapData = new BitmapData(300, 300, true, 0x80FF0000);
        // this must fail, you'll get an exception
        bmp.draw(event.target.content);
        stage.addChild(new Bitmap(bmp));
    }
    
    var binaryLoader:URLLoader = new URLLoader();
    binaryLoader.dataFormat = URLLoaderDataFormat.BINARY;
    binaryLoader.addEventListener(Event.COMPLETE, onBinaryComplete);
    binaryLoader.load(new URLRequest("http://noregret.org/test/wrk.swf"));
    
    var bytesLoader:Loader = new Loader();
    bytesLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBytesComplete);
    
    var directLoader:Loader = new Loader();
    directLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onDirectLoadComplete);
    directLoader.load(new URLRequest("http://noregret.org/test/wrk.swf"));
    

    数据crossdomain.xml的加载:http://noregret.org/crossdomain.xml,但是直接加载时你无法控制加载的swf内容。加载字节然后内容解决问题。

    【讨论】:

    • 我也在尝试显示上述 swf 的预览,但我不知道如何将字节数组转换为影片剪辑。有什么帮助吗?
    • 使用loader.loadBytes()方法创建new Loader(),并等待来自loader.contentLoaderInfoEven.COMPLETEhelp.adobe.com/en_US/FlashPlatform/reference/actionscript/3/…
    • 使用它,我没有收到任何错误,也没有加载 swf。虽然我通常可以毫无问题地加载 swf,但不允许快照。 ldr.loadBytes(raw.data); 并在完整的事件中:loaded_swf = MovieClip(evt.target.bytes);
    • 这一行是错误的:loaded_swf = MovieClip(evt.target.bytes);。加载字节并获取 Event.COMPLETE 后,您可以引用加载的 swf,就像您通常使用 load() 方法加载它一样。 loaded_swf = MovieClip(evt.target.content).
    • 使用正常负载时。我的调试日志会显示类似[SWF] /clothes/bg/bg_10438411_bg.swf - 5363 bytes after decompression 的内容。使用二进制数据时,这些也不显示。
    【解决方案2】:

    这几乎就是沙盒的用途。所以你不能从你不拥有的数据中制作快照。这是一个蹩脚的答案,但as the docs point out,解决它的唯一方法是使用 AIR。

    如果您可以访问其他域或者您认识控制它的人,您可以在他们的站点上放置 crossdomain.xml

    【讨论】:

      【解决方案3】:

      您可以通过一些代理(托管在您自己的服务器上)加载资产。许多托管公司不允许托管任何代理脚本,即使它旨在为应用程序加载资产。

      【讨论】:

        最近更新 更多