我正在将一批150张高清图像加载到我的应用程序中 - 它基本上是一个对象的3D视图。一旦我使用Loader
实例加载图像文件,我将加载器的第一个孩子的bitmapdata存储在Vector中。当所有的加载,我想开始“旋转”对象=意味着我只是交换图像。我拿到了Vector,我有bitmapdatas并将它们一个接一个地绘制到一个画布bitmapdata上。那里没有科学,它都按预期工作。
问题在于,一旦所有图像都被加载并存储在矢量中,并且在将它们绘制到画布之前,它们就不在内存中。这意味着我的3D对象的第一次旋转( - >所有150个绘制的图像)非常慢。第一次旋转后没有问题,一切都是流动的。我的问题是:有没有办法强制图像加载到内存而不将它们绘制到舞台上?我预计一旦加载到app,它们就会被加载到内存中(错误!)。
我尝试使用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);
}
}
答案 0 :(得分:0)
“不在内存中”意味着图像已加载但尚未解码,并且此解码是即时完成的,这会使您观察到的时间变慢。您可以尝试“虚拟”旋转图像,方法是将尚未添加到舞台的位图作为对矢量的每个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.copyPixels(bmpData, bmpData.rect, _destPoint);
_canvas.bitmapData = bmpData;
而不是destPoint
,而且它会起作用。
更新:您的问题可能与最后一点有关,即分配而不是复制。如果您的Bitmap
不是(0,0),那么您只需在_canvas
之上创建另一个Vector.<BitmapData>
对象并使用所需的偏移量,并在其中分配bitmapdatas。我记得当我第一次基于像你一样的copyPixels()
制作多个动画对象,并尝试做_bitmap.bitmapData=_bitmaps[currentFrame]
时,我的动画是抖动的,没有显示正确的帧,但是一旦我做了{{1}一切都变得如此顺利。