C# 奇怪的GDI+;行为

C# 奇怪的GDI+;行为,c#,.net,dispose,C#,.net,Dispose,我已经做了一个方法来压缩图像大小根据图像质量。它的代码是 public static Image CompressImage(string imagePath, long quality) { Image srcImg = LoadImage(imagePath); //Image srcImg = Image.FromFile(imagePath); EncoderParameters parameters = new EncoderParameters(1);

我已经做了一个方法来压缩图像大小根据图像质量。它的代码是

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));
    }
}
现在,当我按原样运行此代码时,在保存srcImg(func#1中的最后一行)时,它会给我一个“通用GDI+异常”,但当我取消第2行的注释并使用image.FromFile加载图像时,一切正常


为什么???

胡乱猜测。。。图像是可识别的。你是在循环中调用这个还是什么?尝试将图像本身放在using()块中?

胡乱猜测。。。图像是可识别的。你是在循环中调用这个还是什么?尝试将图像本身放入using()块?

LoadImage
的末尾,包含图像的文件流被释放。这太早了;文件流需要处于活动状态,以便调用
LoadImage
的方法使用


请参阅MSDN上的

LoadImage
的末尾,包含该映像的文件流被释放。这太早了;文件流需要处于活动状态,以便调用
LoadImage
的方法使用

请参阅MSDN上的

根据:

备注: 您必须在映像的生命周期内保持流打开

此处,您的流位于使用块中,因此在图像生命周期结束之前关闭。

根据:

备注: 您必须在映像的生命周期内保持流打开


此处,您的流位于using块中,因此在映像生命周期结束之前关闭。

您应该重写代码:

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

在这种情况下,使用
构造
是错误的,因为
FileStream
需要处于活动状态才能使用图像。

您应该重写代码:

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

在这种情况下,使用
构造
是错误的,因为
FileStream
需要处于活动状态才能使用图像。

Image.FromFile()存在各种问题

上述语句不会关闭文件流,如果您想再次访问或删除该文件,则会产生问题。我会这样写你的函数

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

这将确保我的文件在使用范围结束时关闭。

Image.FromFile()存在各种问题

上述语句不会关闭文件流,如果您想再次访问或删除该文件,则会产生问题。我会这样写你的函数

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

这将保证我的文件将在使用范围结束时关闭。

修复,但对我来说,Dispose调用是.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();
}

修复,但对我来说,Dispose调用是.net framework中的一个bug

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