在C#中裁剪位图时出现System.OutOfMemoryException

时间:2017-06-12 08:12:13

标签: c# asp.net bitmap

我正在尝试使用ASP文件上传控件上传图像,但是将其从中间裁剪成正方形。这是我的代码,

 public void CropImage(string imagePath)
    {
        //string imagePath = @"C:\Users\Admin\Desktop\test.jpg";
        Bitmap croppedImage;
        int x, y;
        // Here we capture the resource - image file.
        using (var originalImage = new Bitmap(imagePath))
        {
        if (originalImage.Width > originalImage.Height) {
            x = 0;
            y = (originalImage.Width / 2) - (originalImage.Height / 2);
        }
        else if (originalImage.Width < originalImage.Height)
        {
            y = 0;
            x = (originalImage.Height / 2) - (originalImage.Width / 2);
        }
        else { 
            y=x=0;
        }
            int sqrWidth = (originalImage.Width >= originalImage.Height) ? originalImage.Height : originalImage.Width;
            Rectangle crop = new Rectangle(x, y, sqrWidth, sqrWidth);

            // Here we capture another resource.
            croppedImage = originalImage.Clone(crop, originalImage.PixelFormat);

        } // Here we release the original resource - bitmap in memory and file on disk.

        // At this point the file on disk already free - you can record to the same path.
        croppedImage.Save(imagePath, ImageFormat.Jpeg);

        // It is desirable release this resource too.
        croppedImage.Dispose();
    }
    //Updates an agent in the database.
    protected void BtnUpdate_Click(object sender, EventArgs e)
    {
        AgentController agentController = new AgentController();
        AgentContactController agentContactController = new AgentContactController();
        CityController cityController = new CityController();
        DistrictController districtController = new DistrictController();
        ProvinceController provinceController = new ProvinceController();
        CountryController countryController = new CountryController();
        InsurancePortalContext context = new InsurancePortalContext();



        string folderPath = Server.MapPath("~/AdvisersImages/");

        //Check whether Directory (Folder) exists.
        if (!Directory.Exists(folderPath))
        {
            //If Directory (Folder) does not exists. Create it.
            Directory.CreateDirectory(folderPath);
        }

        //Save the File to the Directory (Folder).
        string FilePath = folderPath + Path.GetFileName(ImageUploadUpdate.PostedFile.FileName);

        if (!File.Exists(FilePath))
        {
            ImageUploadUpdate.SaveAs(FilePath);
            CropImage(FilePath);
        }

但是我在

处遇到了内存不足的异常
  

croppedImage = originalImage.Clone(crop,originalImage.PixelFormat);

如果我不在CropImage函数中使用x,y值设置条件块和/或仅保存上传的图像,则不会出现此异常。

提前致谢

1 个答案:

答案 0 :(得分:2)

正如我在评论中提到的那样。如果您的裁剪矩形超出图像界限,则.Clone()会抛出OutOfMemoryException。你可以在这里阅读:
https://msdn.microsoft.com/de-de/library/ms141944(v=vs.110).aspx

考虑具有以下尺寸的输入图像的代码:
宽度:5px
身高:10px

这是你的代码。

if(originalImage.Width > originalImage.Height)
{
   x = 0;
   y = (originalImage.Width / 2) - (originalImage.Height / 2);
}
else if(originalImage.Width < originalImage.Height)
{
   y = 0;
   x = (originalImage.Height / 2) - (originalImage.Width / 2);
}
else
{
   y = x = 0;
}

int sqrWidth = (originalImage.Width >= originalImage.Height) ? originalImage.Height : originalImage.Width;
Rectangle crop = new Rectangle(x, y, sqrWidth, sqrWidth);

5x10图像会落入else if的情况 y设置为 0 ,x设置为((10/2)= 5) - (5/2)= 2)= 3
然后sqrWidth设置为 10

接下来,您尝试克隆以下rect:
x = 3,y = 0,w = 10,h = 10

瞧,你的矩形超出了图像的范围。你需要修复你的裁剪逻辑。