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.