简体   繁体   中英

C# Bitmap image using a lot of RAM during runtime

I made a tilemap generator today, and I noticed that when importing images of size 128x128 pixels and stitching them together (tilemap) into one large bitmap (8192x8192 pixels; 64x64 tiles) it uses ~250MB RAM when the output of the image to disk (BinaryWriter) is only <400KB. I don't understand why internally it's using so much RAM.

DEFAULT_TILE_SIZE = 128 DEFAULT_SIZE = 8192

Here's the code here:

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;
}

The Bitmap you create is 8192 x 8192, and it is all in memory before written to disk. Each pixel in the Bitmap requires 4 bytes (red, green, blue, alpha). Therefore, the memory (RAM) required is 8192 x 8192 x 4 bytes = 256MB.

When written to disk, you are probably saving it in PNG format, which uses a loss-less compression to reduce the file size.

PS - As Matthew pointed out in the comments, you should also wrap the src Bitmap with a "using", or dispose of it properly.

I would also create the Graphics once, rather than every tile, as you use it again and again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM