我尝试使用BitmapData方法从大型BitmapData(约2000x4000)获得小copyPixels(约500x500)。在每个帧期间,我将获得一个带有copyPixels调用的小型BitmapData。
在一帧中,滞后变得非常高。使用Adobe Scout CC,我发现" UnCompress Image"耗资200-300毫秒,但在其他一些框架。因为当我用小源BitmapData调用copyPixels时没有发生,我想原因是源BitmapData太大了?任何帮助将不胜感激。
答案 0 :(得分:0)
嗯,这不是你问题的答案。这是为了说明copyPixels()
没有明显的问题。这是一个简单的独立测试,您可以将其复制并粘贴到新项目中,看看会发生什么(只需将有问题的图像放入输出文件夹)。除了copyPixels()
之外,我删除了任何耗时的测试。
似乎问题出在其他地方,需要更多关于问题的信息。
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.getTimer;
[SWF(backgroundColor="0xFFFFFF", width="1024", height="768", frameRate="60")]
public class StackCopyPixels extends Sprite
{
private var sourceImage:BitmapData;
private var loader:Loader;
private var targetImage:BitmapData;
private var timeLabel:TextField;
private var log:String = "";
private var count:int = 0;
private var sizeLimit:int;
private var sourceRect:Rectangle;
private var destPoint:Point;
public function StackCopyPixels()
{
stage.align = StageAlign.TOP_LEFT;
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
// in my case the image is 3450x720, so it's bigger than BitmapData limit of 2880 px
// (which I figured could be the source of the problem)
loader.load(new URLRequest("image.png"));
targetImage = new BitmapData(500, 500, true, 0);
addChild(new Bitmap(targetImage));
timeLabel = new TextField();
timeLabel.autoSize = TextFieldAutoSize.LEFT;
timeLabel.background = true;
timeLabel.multiline = true;
timeLabel.wordWrap = false;
addChild(timeLabel);
}
protected function onImageLoaded(event:Event):void
{
var image:Bitmap = loader.content as Bitmap;
sourceImage = image.bitmapData;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
sizeLimit = Math.floor(sourceImage.width/targetImage.width);
sourceRect = targetImage.rect;
destPoint = new Point();
}
protected function onEnterFrame(event:Event):void
{
var s:int = getTimer();
sourceRect.x = (count%sizeLimit)*500;
sourceRect.y = Math.floor(Math.random()*(sourceImage.height-sourceRect.height));
targetImage.copyPixels(sourceImage, sourceRect, destPoint);
var elapsed:int = getTimer()-s;
if (elapsed > (1000/60*2)) {
log += "\nslow at "+count+" (position "+(count%sizeLimit)+"): "+elapsed;
}
timeLabel.text = elapsed.toString()+log;
count++;
}
}
}
答案 1 :(得分:0)
我不知道这是否是解决方案(很难说我们没有其他信息,但请考虑一下:
每次使用'图像时,都需要解压缩。即使你维护它的bitmapData。听起来很有趣。因此,我们假设您要显示(甚至访问图像)刚加载的图像。 Flash将拍摄图像,对其进行解压缩(很可能是您正在经历的击中)并显示它或在其上调用方法bitmapData。解码内容需要不同的时间,具体取决于位图的大小。
在许多情况下这是不可接受的,因此您可以在此处查看解决方法:Keeping Bitmaps Decompressed。这个想法只是简单地“ping”bitmapData或者每隔X秒就对它执行一些方法,这样Flash运行时就不会从内存中释放它(只有当图像没有显示在显示列表的某个地方时才释放它),否则它将不得不再次解压缩。或者你可以只在显示列表上显示图像......在这种情况下它肯定是解压缩的。
我自己遇到了同样的问题(按序列显示150个高清图像) - 第一次运行总是不稳定,如果动画没有停止因为停止将连续运行从内存中清除,则连续运行正常。访问位图中像素的方法运行得很完美(即使我实现的方式有点不同;我还没读过那篇文章)。