tags:

views:

69

answers:

6

I have made a method to CompressImageSize according to Image quality. The code for it is

public static Image CompressImage(string imagePath, long quality)
{
    Image srcImg = LoadImage(imagePath);
    //Image srcImg = Image.FromFile(imagePath);

    EncoderParameters parameters = new EncoderParameters(1);
    parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);

    ImageCodecInfo encoder = GetCodecInfo("image/jpeg");

    srcImg.Save("d:\\creatives\\abcd123.jpg", encoder, parameters);
}

public static Image LoadImage(string filename)
{
    using (FileStream fs = new FileStream(filename, FileMode.Open))
    {
        return(Image.FromStream(fs));
    }
}

Now, when i run this code as is it gives me a 'Generic GDI+ exception' while saving the srcImg(last line in func #1), BUT when i uncomment the 2nd line and load the image using Image.FromFile everything works fine.

Why ??

A: 

A wild guess... Image is IDisposable. Are you calling this in a loop or something? Try putting your Image itself in a using() block?

Dave Markle
A: 

In the end of LoadImage, the FileStream containing the Image is disposed. This is too soon; the file stream needs to be alive for use by the method calling LoadImage.

See using on MSDN.

bzlm
+3  A: 

According to MSDN:

Remarks: You must keep the stream open for the lifetime of the Image.

Here your stream is in a using block and thus closed before the end of the lifetime of the image.

Locksfree
A: 

You should rewrite your code:

public static Image LoadImage(string filename)
{
    FileStream fs = new FileStream(filename, FileMode.Open);        
    return Image.FromStream(fs);        
}

Construction using is wrong in this case because FileStream needs to be alive for using your Image.

DreamWalker
A: 

There are various issues with Image.FromFile()...

Image srcImg = Image.FromFile(imagePath);

The above statement will not close the file stream and that will create problems if you want to access file again or delete it. I would write your function this way.

public static Image CompressImage(string imagePath, long quality)
{
    using(FileStream fs = File.OpenRead(imagePath)){
       Image srcImg = Image.FromStream(fs);    

       EncoderParameters parameters = new EncoderParameters(1);    
       parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);    
       ImageCodecInfo encoder = GetCodecInfo("image/jpeg");    
       srcImg.Save("d:\\creatives\\abcd123.jpg", encoder, parameters);
    }
}

This will guarentee that my file will be closed at the end of using scope.

Akash Kava
A: 

Fix , but for me the Dispose call is a bug in .net framework...

public static Image CompressImage(string imagePath, long quality)
{
    Image srcImg = LoadImage(imagePath);
    //Image srcImg = Image.FromFile(imagePath);

    EncoderParameters parameters = new EncoderParameters(1);
    parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);

    ImageCodecInfo encoder = GetCodecInfo("image/jpeg");

    srcImg.Save("d:\\creatives\\abcd123.jpg", encoder, parameters);
srcImg.Dispose();
}
Arabcoder