0

I'm trying to upload an image with an ASP fileupload control but crop it into a square from the middle. this is my code,

 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);
        }

but I'm getting the out of memory exception at,

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

If I don't use the x,y value setting conditional block in CropImage function and/or only save the uploaded image as is, this exception doesn't come.

thanks in advance

PeeBee
  • 149
  • 1
  • 1
  • 13
  • Possible duplicate of [C# Image.Clone Out of Memory Exception](https://stackoverflow.com/questions/199468/c-sharp-image-clone-out-of-memory-exception) – Tamás Szabó Jun 12 '17 at 08:14
  • It is important that you **freeze** the bitmap. Check the answer to one of my questions: https://stackoverflow.com/questions/26300379/large-1-bit-per-pixel-bitmap-causes-outofmemoryexception – Noel Widmer Jun 12 '17 at 08:14
  • Where exactly do I freeze the bitmap? can you share an example? – PeeBee Jun 12 '17 at 08:18
  • Well aside from the freeze issue. Did you read the manual? https://msdn.microsoft.com/de-de/library/ms141944(v=vs.110).aspx. It says: Throws OutOfMemoryException when *rect is outside of the source bitmap bounds.* I assume this is your main problem. – Noel Widmer Jun 12 '17 at 08:27
  • 1
    You should really start to accept answers from other people if they correctly answered your question. I see that you often don't accept answers. People will start to notice and not respond to your questions at some point. – Noel Widmer Jun 12 '17 at 10:13

1 Answers1

2

As I mentioned in the comments. .Clone() throw an OutOfMemoryException if your crop rect is out of the image's bounds. You can read it up right here:
https://msdn.microsoft.com/de-de/library/ms141944(v=vs.110).aspx

Consider your code with the input image that has the following size:
width: 5px
height: 10px

This is your code.

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);

The 5x10 image would fall into the else if case.
There y gets set to 0 and x gets set to ((10 / 2) = 5) - (5 / 2) = 2) = 3.
Then sqrWidth gets set to 10.

Next you try to clone the following rect:
x = 3, y = 0, w = 10, h = 10

And voila your rectangle is out of the image's bounds. You need to fix your cropping logic.

Noel Widmer
  • 4,444
  • 9
  • 45
  • 69