代码之家  ›  专栏  ›  技术社区  ›  Storm

奇怪的GDI+行为

  •  0
  • Storm  · 技术社区  · 15 年前

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

    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+异常”,但是当我取消对第二行的注释并使用image.fromfile加载图像时,一切正常。

    为什么??

    6 回复  |  直到 15 年前
        1
  •  0
  •   AndreyAkinshin    15 年前

    您应该重写代码:

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

    施工 using 在这种情况下是错误的,因为 FileStream 需要活着才能使用你的图像。

        2
  •  3
  •   Locksfree    15 年前

    根据 MSDN :

    评论 : 您必须在图像的生命周期内保持流的打开状态。

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

        3
  •  0
  •   Dave Markle    15 年前

    一个疯狂的猜测…图像可IDisposable。你是在循环中调用这个还是什么?尝试将图像本身放入using()块中?

        4
  •  0
  •   bzlm    15 年前

    在最后 LoadImage ,将释放包含该映像的文件流。这太早了;文件流必须是活动的,才能由方法调用使用 隐匿 .

    using 在msdn上。

        5
  •  0
  •   Akash Kava    15 年前

    image.fromfile()存在各种问题。

    Image srcImg = Image.FromFile(imagePath);
    

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

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

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

        6
  •  0
  •   Mandrake    15 年前

    修复,但对我来说,Dispose调用是.NET框架中的一个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();
    }