创建大量位图图像并将其保存为每像素图像一位时,物理内存使用异常
本文关键字:图像 一位 物理内存 异常 像素 位图 保存 创建 | 更新日期: 2023-09-27 18:30:50
我正在尝试从 base 1 字符串创建大量每像素 64 位的 bmp 图像并保存。根据要求,在短时间内创建非常大量的图像(在短时间内平均创建50,000到1,00,000个)。我正在使用下面的代码。
public void CreateoneBppImageAndSave(String base64ImageString,String ImagePathToSave)
{
byte[] byteArray = Convert.FromBase64String(base64ImageString);
System.Drawing.Image img = byteArrayToImage(byteArray);
Bitmap objBitmap = new Bitmap(img);
BitmapData bmpData = objBitmap.LockBits(new Rectangle(0, 0, objBitmap.Width, objBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
Bitmap oneBppBitmap = new Bitmap(objBitmap.Width, objBitmap.Height, bmpData.Stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, bmpData.Scan0);
oneBppBitmap.Save(ImagePathToSave, ImageFormat.Bmp);
img.Dispose();
objBitmap.Dispose();
objBitmap.UnlockBits(bmpData);
oneBppBitmap.Dispose();
}
private Image byteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
return Image.FromStream(ms);
}
}
这里的物理内存使用率非常高。通常生成的图像大小为 200x200 到 754x1024 。在一定时间后,物理内存使用量达到极端和内存不足异常被抛出。物理内存每 5-10 秒增加 0.01 GB。请帮助我在内存使用方面优化代码。
你objBitmap
上调用LockBits
,但你在oneBppBitmap
上调用UnlockBits
。您应该在调用锁定的同一对象上调用解锁。
至于我在评论中提到的using
语句,使用 语句会变成这个
using(SomeType obj = new SomeType())
{
// Some code
}
在相当于这个
SomeType obj = new SomeType())
try
{
// Some code
}
finally
{
obj.Dispose();
}
这保证了即使抛出异常// Some Code
释放操作仍然会发生。您的代码(就像现在一样)如果创建和释放之间的任何函数引发异常,则不会释放其任何对象。
这是一个重写的版本,其中包含我提到的所有更正以及其他一些更正。
public void CreateoneBppImageAndSave(String base64ImageString,String ImagePathToSave)
{
byte[] byteArray = Convert.FromBase64String(base64ImageString);
using(Image img = byteArrayToImage(byteArray))
using(Bitmap objBitmap = new Bitmap(img))
{
BitmapData bmpData = objBitmap.LockBits(new Rectangle(0, 0, objBitmap.Width, objBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
try
{
using(Bitmap oneBppBitmap = new Bitmap(objBitmap.Width, objBitmap.Height, bmpData.Stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, bmpData.Scan0))
{
oneBppBitmap.Save(ImagePathToSave, ImageFormat.Bmp);
}
}
finally
{
//put the unlock in a finally to make sure it happens.
objBitmap.UnlockBits(bmpData);
}
}
}
编辑:如果这真的在你的代码中
objBitmap.Dispose();
objBitmap.UnlockBits(bmpData);
这就是问题的根源,在释放后,您不应该在类上调用任何方法。这是using
的另一个好处,你不能延迟调用方法,因为当你离开using
块时,变量会超出范围。