c#-创建大量位图图像并将其保存为每个像素图像一位时,异常的物理内存使用情况

我正在尝试从base 64字符串中创建大量每像素bmp图像1位并保存.根据要求,可在短时间内创建大量图像(短时间内平均创建50,000至1,000,000).我正在使用以下代码.public void CreateoneBppImageAndSave(String base64Imag...

我正在尝试从base 64字符串中创建大量每像素bmp图像1位并保存.根据要求,可在短时间内创建大量图像(短时间内平均创建50,000至1,000,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);
        }
    }

这里的物理内存使用率很高.通常生成的图像大小为200×200到754×1024.在一定的持续时间后,物理内存使用率达到极限并抛出内存不足异常.物理内存每5-10秒增加0.01 GB.请帮助我在内存使用方面优化代码.

解决方法:

您在objBitmap上调用LockBits,但是在oneBppBitmap上调用UnlockBits.您应该在调用lock on的同一对象上调用unlock.

至于我在评论中提到的using语句,using语句可以将其变为

using(SomeType obj = new SomeType())
{
   // Some code
}

相当于这个

SomeType obj = new SomeType())
try
{
    // Some code
}
finally
{
    obj.Dispose();
}

这样可以保证即使在//一些代码中引发了异常,处置操作仍然会发生.现在,如果您的代码在创建和处理之间的任何函数引发异常,则不会处理其任何对象.

这是重写的版本,其中包含我提到的所有更正以及其他一些更正.

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块时,变量超出了范围.

本文标题为:c#-创建大量位图图像并将其保存为每个像素图像一位时,异常的物理内存使用情况

基础教程推荐