我今天制作了一个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;
}
答案 0 :(得分:3)
您创建的位图是8192 x 8192,在写入磁盘之前全部都在内存中。位图中的每个像素都需要4个字节(红色,绿色,蓝色,alpha)。因此,所需的存储器(RAM)是8192 x 8192 x 4字节= 256MB。
写入磁盘时,您可能将其保存为PNG格式,该格式使用无损压缩来减小文件大小。
PS - 正如Matthew在评论中指出的那样,你还应该用“使用”来包装src Bitmap,或者正确处理它。
我还会一次又一次地使用它来创建一次Graphics,而不是每个tile。