【问题标题】:Loading images does not load them into memory加载图像不会将它们加载到内存中
【发布时间】:2014-02-22 01:02:30
【问题描述】:

我正在将一批 150 张高清图像加载到我的应用程序中 - 它基本上是一个对象的 3D 视图。一旦我使用Loader 实例加载图像文件,我将加载器的第一个孩子的位图数据存储在向量中。加载完所有内容后,我想开始“旋转”对象=这意味着我只是在交换图像。我将拥有位图数据的 Vector 一个接一个地绘制到画布位图数据上。那里没有科学,一切都按预期工作。

问题在于,一旦所有图像都加载并存储在矢量中,并且在它们被绘制到画布之前,它们就不会在内存中。这意味着我的 3D 对象(-> 绘制的所有 150 张图像)的第一次旋转非常慢。第一次旋转后没有问题,一切都是流畅的。我的问题是:有没有办法强制将图像加载到内存中而不将它们绘制到舞台上?我希望它们在加载到应用程序后会简单地加载到内存中(错误!)。

我尝试使用 addChild() 而不是将它们绘制到画布位图上,结果相同。我不认为代码是必要的,但以防万一:

private var _loaders:Vector.<Loader>;
private static const NAME:String = "img_00";
private static const MIN:uint = 0;
private static const MAX:uint = 150;
private var _loaded:uint = 0;
private var _currentFrameIndex:uint = 0;
private var _canvas:Bitmap;
private var _bitmaps:Vector.<BitmapData>;
private var _destPoint:Point;

public function loadImages():void {
    var s:String;
    for(var i:int=MIN; i<=MAX; i++) {
        if(i < 10) s = "00" + i;
        else if(i < 100) s = "0" + i;
        else s = i.toString();
        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadHandler);
        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadHandler);
        loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadHandler);
        loader.load(new URLRequest("images/JPEG/"+ NAME + s + ".jpg"));
        _loaders.push(loader);
    }
}

private function loadHandler(e:Event):void {
    _loaded++;

    if(_loaded > (MAX - MIN)) {
        _bitmaps = new Vector.<BitmapData>(_loaders.length);
        for(var i:int=0; i<_loaders.length; i++) {
            var loader:Loader = _loaders[i];
            _bitmaps[i] = Bitmap(loader.getChildAt(0)).bitmapData;
            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadHandler);
            loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loadHandler);
            loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadHandler);
        }
        setFrame(0);
        dispatchEvent(new Event(LOAD_COMPLETE));
    }
}

public function setFrame(frame:uint):void {
    if(frame >= 0 && frame < _bitmaps.length) {
        _currentFrameIndex = frame;
        var bmpData:BitmapData = _bitmaps[_currentFrameIndex];
        _canvas.bitmapData.copyPixels(bmpData, bmpData.rect, _destPoint);
    }
}

【问题讨论】:

    标签: actionscript-3 memory bitmap bitmapdata


    【解决方案1】:

    “不在内存中”表示图像已加载,但尚未解码,并且此解码是即时完成的,这需要您观察到的缓慢时间。您可以尝试通过将尚未添加到舞台的位图作为对矢量的每个 bitmapDatas 的引用来“虚拟地”旋转图像。制作一个进度条,显示已经解码了多少矢量,一旦发生这种情况,显示位图并为用户提供平滑的旋转。

    addEventListener(Event.ENTER_FRAME,prerender);
    var b:Bitmap=new Bitmap();
    /* optional
        b.x=stage.stageWidth;
        b.y=stage.stageHeight;
        addChild(b);
    */
    var vi:int=0;
    var sh:Shape=new Shape();
    sh.graphics.lineStyle(4,0,1); // a simple progress bar
    sh.graphics.moveTo(0,0);
    sh.graphics.lineTo(100,0);
    sh.scaleX=0;
    sh.x=stage.stageWidth/2-50; // centered by X
    sh.y=stage.stageHeight/2;
    addChild(sh);
    function prerender(e:Event):void {
        if (vi==_bitmaps.length) {
            // finished prerender
            removeEventListener(Event.ENTER_FRAME, prerender);
            removeChild(sh);
            // removeChild(b); if optional enabled
            setFrame(0);
            return;
        }
        b.bitmapData=_bitmaps[vi];
        vi++;
    }
    

    此外,如果您不打算更改该位图数据,最好将bitmapData 属性分配给Bitmap 对象。因此,您只需使用_canvas.bitmapData = bmpData; 而不是您的_canvas.bitmapData.copyPixels(bmpData, bmpData.rect, _destPoint);,它就会起作用。

    更新:您的问题也可能指向最后一点,即分配而不是复制。如果您的 destPoint 不是 (0,0),您只需在您的 _canvas 顶部创建另一个具有所需偏移量的 Bitmap 对象,并在其中分配位图数据。我记得当我第一次像你一样基于单个Vector.&lt;BitmapData&gt; 制作多个动画对象并尝试做copyPixels() 时,我的动画抖动并且没有显示正确的帧,但是一旦我做了_bitmap.bitmapData=_bitmaps[currentFrame] 一切都像你一样顺利应该是的。

    【讨论】:

    • 我猜就是这样 - 图像尚未解码(也可以解释内存使用情况和速度慢)。好吧,太糟糕了,我想用户将不得不再等一会儿。谢谢!
    • PS:渲染位图必须在显示列表中并且必须可见。否则它将不起作用,因此在这种情况下似乎 addChild/removeChild 不是可选的。 (所以它可以只在主画布上呈现)。
    • 有趣。好的,我很高兴你知道了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    相关资源
    最近更新 更多