【问题标题】:An alternative to bitmapdata with less memory usage?内存使用量更少的位图数据的替代方案?
【发布时间】:2013-11-14 22:57:06
【问题描述】:

我使用一个非常大的 BitmapData 作为我的平台游戏的路径图,但是我只使用 4 个特定值的像素,而不是 4294967295。

将这个 Bitmapdata 转换为 2 个 2D 布尔向量会节省一些内存吗? 如果确实如此,那么性能如何,执行以下操作会更快还是更慢:

MapGetPixel(x:int, y:int):int
{
    return MapBoolFirst[x][y] + MapBoolSecond[x][y]*2;
}

而不是位图数据类getPixel32(x:int, y:int):uint

简而言之,我正在寻找一种方法来减小尺寸和/或优化我的 4 色位图数据。

编辑: 使用我的布尔方法显然消耗的内存是位图数据的 2 倍。 我猜布尔值在内存中占用的内存不止一位,否则就太容易了。所以我正在考虑对 int 进行移位,因此有一个 int 存储几个像素的值,但我不确定这个......

编辑 2: 使用 int bitshifts 我可以将 16 个像素的数据管理到一个 int 中,这个技巧应该可以节省一些内存,即使它可能会影响性能。

【问题讨论】:

    标签: actionscript-3 flash vector bitmapdata


    【解决方案1】:

    Bitshifting 将是最优化内存的处理方式。性能方面,这应该不是太大的问题,除非您需要在每一帧中轮询很多请求。 AS 的问题是布尔值是 4 位 :(

    在我看来,你可以在不同的情况下处理它:

    1) 为命中检测创建较低分辨率的纹理,通常可以将其缩小 4 倍 (256x256 --> 64x64)

    2) 使用某种技术将该数据保存到某种存储中(bool 是最简单的,但如果它太大,那么您需要为它找到另一种解决方案)

    3) 做整数解(我以前没有使用过位移,所以我认为这将是一个有趣的挑战,这就是结果)

    而且该解决方案比用于布尔的解决方案要小得多,也更难理解:/

    public class Foobar extends MovieClip {
        const MAX_X:int = 32;
        const MAX_Y:int = 16;
    
        var _itemPixels:Vector.<int> = new Vector.<int>(Math.ceil(MAX_X * MAX_Y / 32));
    
        public function Foobar() {
            var pre:Number = System.totalMemory;
            init();
            trace("size=" + _itemPixels.length);
            for (var i = 0; i < MAX_Y; ++i) {
                for (var j = 0; j < MAX_X; ++j) {
                    trace("item=" + (i*MAX_X+j) + "=" +  isWalkablePixel(j, i));
                }
            }
            trace("memory preInit=" + pre);
            trace("memory postInit=" + System.totalMemory);
        }
    
        public function init() {
            var MAX_SIZE:int = MAX_X * MAX_Y;
            var id:int = 0;
            var val:int = 0;
            var b:Number = 0;
            for(var y=0; y < MAX_Y; ++y) {
                for (var x = 0; x < MAX_X; ++x) {
                    b = Math.round(Math.random()); //lookup the pixel from some kind of texture or however you expose the items
                    if (b == 1) {
                        id = Math.floor((y * MAX_X + x) / 32);
                        val = _itemPixels[id];
                        var it:uint = (y * MAX_X + x) % 32;
                        b = b << it;
                        val |=  b;
                        _itemPixels[id] = val;
                    }
                }
            }
        }
    
        public function isWalkablePixel(x, y):Boolean {
            var val:int = _itemPixels[Math.floor((y * MAX_X + x) / 32)];
            var it:uint = 1 << (y * MAX_X + x) % 32;
            return (val & it) != 0;
        }
    }
    

    【讨论】:

    • 使用 & 代替 % 也更快。所以像 1 快
    • 只是一点警告:我发现在运行某些代码之前和之后比较System.totalMemory 并不一定反映那段代码占用了多少内存向上。 System.totalMemory 只返回 Flash Player 占用了多少内存,我怀疑 Flash Player 分配的内存可能比它实际需要的多一点,这导致 System.totalMemory 在您的代码创建新对象时并不总是增加。
    • 我不会使用 1),因为地图包含在这里会被压碎的壁架。您的 3) 代码几乎就是我所想的那样
    • @CreativeMagic:酷没有想过这是使用 mod 的有效替代方案。 Strille:你是对的,但是,对于这个有限的场景,当我用布尔结果运行它几次,然后用整数运行时,它的结果要小得多,但对于任何动态语言来说,它总是相同的数字,它不会显示“真实”的内存使用情况。
    【解决方案2】:

    一个简单的改进是使用ByteArray 而不是BitmapData。这意味着每个“像素”只占用 1 个字节而不是 4 个。这仍然有点浪费,因为每个像素只需要 2 位而不是 8 位,但它比使用 BitmapData 少得多。如果您需要在每个像素存储超过 4 个值,它还为您提供了一些“增长空间”,而无需在以后进行任何重大更改。

    ByteArray.readByte()/ByteArray.writeByte() 可以处理整数,所以使用起来非常方便。当然,调用writeByte()时只写入整数的低8位。

    您将 ByteArray.position 设置为您希望下一次读取或写入开始的点(从 0 开始的索引)。

    总结一下:将 ByteArray 想象成一个一维的整数数组,其值为 0-255。

    【讨论】:

      【解决方案3】:

      这是结果,顺便说一下,我使用的是导入的 8 位彩色 .png,不确定当他转换为 位图数据。

      内存使用:

      • 位图数据:100%
      • 双布尔向量:200%
      • 内部位移:12%

      所以 int bitshifting 胜出,它的工作方式与十六进制颜色分量几乎相同,但在这种情况下,我存储 16 个分量(2 位像素值)而不是 4 个 ARGB:

      var pixels:int = -1;// in binary full of 1
      for (var i:int = 0; i < 16; i++)
          trace("pixel " + (i + 1) +" value : " + (pixels >> i * 2 & 3));
      

      按预期输出: "像素 i 值:3"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-13
        • 1970-01-01
        • 2020-11-01
        • 2011-04-27
        • 1970-01-01
        • 2018-10-12
        • 2013-08-01
        • 1970-01-01
        相关资源
        最近更新 更多