运行期间使用大量RAM的C#位图图像

时间:2015-05-09 03:28:43

标签: c# bitmap ram

我今天制作了一个tilemap生成器,我注意到当导入大小为128x128像素的图像并将它们拼接在一起(tilemap)成一个大位图(8192x8192像素; 64x64 tile)时,它在图像输出时使用~250MB RAM到磁盘(BinaryWriter)只有<400KB。我不明白为什么在内部使用这么多内存。

DEFAULT_TILE_SIZE = 128 DEFAULT_SIZE = 8192

这是以下代码:

public static Bitmap GenerateTileMapFromDirectory(string path, int tileSize = DEFAULT_TILE_SIZE)
{
    if (!Directory.Exists(path)) throw new DirectoryNotFoundException();
    Bitmap bmp = new Bitmap(DEFAULT_SIZE, DEFAULT_SIZE);
    int x = 0, y = 0;
    foreach (string file in Directory.GetFiles(path))
    {
        string ext = Path.GetExtension(file);
        if (ext.ToLower() == ".png")
        {
            Bitmap src = (Bitmap)Bitmap.FromFile(file);
            if (src.Width != tileSize || src.Height != tileSize)
            {
                //Log that PNG was not correct size, but resize it to fit constraints...
                Console.WriteLine(Path.GetFileName(file) + " has incorrect size ... Resizing to fit");
                src = new Bitmap(src, tileSize, tileSize);
            }
            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
            {
                g.DrawImage(src, x, y, tileSize, tileSize);
            }
            src = null;
        }
        else
        {
            Console.WriteLine(Path.GetFileName(file) + " is not a PNG ... Ignoring");
            continue;
        }
        if (x < bmp.Width) x += tileSize;
        if (x == bmp.Width)
        {
            x = 0;
            y += tileSize;
        }
        if (y == bmp.Height) break;
    }


    //For generation verification, uncomment the following two lines.
    //if (File.Exists("D:\\output.png")) File.Delete("D:\\output.png");
    //if (bmp!=null) bmp.Save("D:\\output.png");
    return bmp;
}

1 个答案:

答案 0 :(得分:3)

您创建的位图是8192 x 8192,在写入磁盘之前全部都在内存中。位图中的每个像素都需要4个字节(红色,绿色,蓝色,alpha)。因此,所需的存储器(RAM)是8192 x 8192 x 4字节= 256MB。

写入磁盘时,您可能将其保存为PNG格式,该格式使用无损压缩来减小文件大小。

PS - 正如Matthew在评论中指出的那样,你还应该用“使用”来包装src Bitmap,或者正确处理它。

我还会一次又一次地使用它来创建一次Graphics,而不是每个tile。