• [转载]GDI+中发生一般性错误


    注:第一次写博客,把自己遇到的问题和收集的资料记录在博客上。
    在开发.NET应用中,使用 System.Drawing.Image.Save 方法而导致“GDI+ 中发生一般性错误”的发生,通常有以下三种原因:
    1. 相应的帐户没有写权限。
    解决方法:赋予 NETWORK SERVICE 帐户以写权限。
    2. 指定的物理路径不存在。
    解决方法:
    在调用 Save 方法之前,先判断目录是否存在,若不存在,则创建。
    if (!Directory.Exists(dirpath))
    Directory.CreateDirectory(dirpath);
    3. 保存的文件已存在并因某种原因被锁定。
    解决方法:
    重启IIS,解除锁定。并在代码中使用 using 语句,确保释放 Image 对象所使用的所有资源。

    我遇到的情况:
          在先用openFileDialog打开图片文件,然后用saveFileDialog保存文件时就出现了 “GDI+中发生一般性错误”,我当时就想到是打开的文件还没有释放出来,于是用openFileDialog1.Dispose()来释放,可是没有成功。同样从一个MemorySream 实例打开一个Image后,立即关闭了这个流,结果在Image.Save时也会发生这种错误。我“摆渡”了很久都是遇到和我一样问题的人,CSDN上面的同志也没有给出一个实用的答案。最后终于还是在微软的网站上找到了答案:(以下是官方解决办法)
    症状
    Bitmap 对象或一个 图像 对象从一个文件, 构造时该文件仍保留锁定对于对象的生存期。 因此, 无法更改图像并将其保存回它产生相同的文件。

    替代方法
    •    创建非索引映像。
    •    创建索引映像。
    这两种情况下, 原始 位图 上调用 Bitmap.Dispose() 方法删除该文件上锁或删除要求, 流或内存保持活动。

    创建非索引图像
    即使原始映像被索引格式中该方法要求新图像位于每像素 (超过 8 位 -) -, 非索引像素格式。 此变通方法使用 Graphics.DrawImage() 方法来将映像复制到新 位图 对象:
    1.    构造从流、 从内存, 或从文件原始 位图 。
    2.    创建新 位图 的相同大小, 带有是超过 8 位 - - 像素 (BPP) 每像素格式。
    3.    使用 Graphics.FromImage() 方法以获取有关二 位图 Graphics 对象。
    4.    用于 Graphics.DrawImage() 绘制首 位图 到二 位图 。
    5.    用于 Graphics.Dispose() 处置是 图形 。
    6.    用于 Bitmap.Dispose() 是首 位图 处置。

    创建索引映像
    此解决办法在索引格式创建一个 Bitmap 对象:
    1.    构造从流、 从内存, 或从文件原始 位图 。
    2.    创建新 位图 具有相同的大小和像素格式作为首 位图 。
    3.    使用 Bitmap.LockBits() 方法来锁定整个图像对于两 Bitmap 对象以其本机像素格式。
    4.    使用 Marshal.Copy 函数或其他内存复制函数来从首 位图 复制到二 位图 图像位。
    5.    使用 Bitmap.UnlockBits() 方法可以解锁两 Bitmap 对象。
    6.    用于 Bitmap.Dispose() 是首 位图 处置。
    由于外国人的思维和我们不一样,我重新用实例解释一下,我这里使用的是创建非索引图像。
    private void ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    //创建一个bitmap类型的bmp变量来读取文件。
                    Bitmap bmp = new Bitmap(openFileDialog1 .FileName );
                    //新建第二个bitmap类型的bmp2变量,我这里是根据我的程序需要设置的。
                    Bitmap bmp2 = new Bitmap(1024, 768, PixelFormat.Format16bppRgb555);
                    //将第一个bmp拷贝到bmp2中
                    Graphics draw = Graphics.FromImage(bmp2);
                    draw.DrawImage(bmp,0,0);
                    pictureBox1.Image = (Image)bmp2 ;//读取bmp2到picturebox
                    FILE = openFileDialog1.FileName;
                    openFileDialog1.Dispose();
                    draw.Dispose();
                    bmp.Dispose();//释放bmp文件资源
                }
            }
    通过以上的读取文件,在保存的时候就不会出现错误了。http://www.cnblogs.com/wudingfeng/archive/2008/07/24/1250564.html

    *********************************************************************************************

    我写的一个生成缩略图程序, 生成gif,bmp,png 文件都可以, 就是不能生成jpg 文件, 何解?? 

    //按比例缩小上传的图片 
    System.Drawing.Image img; 
    img = System.Drawing.Image.FromFile(all); 
    float width = img.Width; 
    float height = img.Height; 
    float newwidth = 0; 
    float newheight = 0; 
    if (width > height) 

    newwidth = 135; 
    newheight = height / width * newwidth; 

    else 

    newheight = 135; 
    newwidth = width / height * newheight; 

    System.Drawing.Image outimg = img.GetThumbnailImage((int)newwidth,(int)newheight,null,IntPtr.Zero); 
    string newfiles = path + newfilename + ".jpg"; 
    outimg.Save(newfiles); 

    outimg.Dispose(); 
    img.Dispose();  

    -------------------------------------------------------------------------------------------

    绘图坐标超过了画布大小。建议先把画布设大写,看看效果再确定实际大小

    跟画布大小应该是无关的, 
    如果上传jpg文件, 用以下方法保存是会报GDI 中发生一般性错误, 
    outimg.Save(newfiles,System.Drawing.Imaging.ImageFormat.Jpeg); 
    如果改成outimg.Save(newfiles,System.Drawing.Imaging.ImageFormat.Gif) 就能顺利生成, 
    但改成outimg.Save(newfiles,System.Drawing.Imaging.ImageFormat.Gif) 后, 上传gif文件生成缩略图就报GDI 中发生一般性错误, 现在连问题的根源都不清楚, 唉...

    监测一下你的newwidth和newheight是不是未预期的数据

    检查是否是权限问题 
    1. 确认没有同名jpg文件存在 
    2. 确认aspnet或者network service有覆盖文件等相应权限

    vivianfdlpw() 一言惊醒梦中人啊!! 果然是重名了!!!

    **************************************************************************************

    private void DrawImg(int width)
       {
       //图片的地址
        string path=String.Format(@"D:共享文件夹EnterpriseLicences1123.jpg");

       //保存水印图片的文件夹
        string catchPath=Server.MapPath(@".. empcache");


        Image newImage = Image.FromFile(path);    //取出图片 
       
        if(width==0)
        {
         width=newImage.Width;
        }
        int hight=newImage.Height*width/newImage.Width;
        System.Drawing.Bitmap bitmap=new Bitmap(width,hight); 
        System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        g.Clear(System.Drawing.Color.Transparent);
        g.DrawImage(newImage,0,0,width,hight);

     

       //水印图片
        Bitmap copyImage = (Bitmap)Bitmap.FromFile(Server.MapPath(@"..ImagesEnterpriseLisenceLogos.gif"));


        copyImage.MakeTransparent(Color.White);
       
        float copyW=width*4/10; float copyH=copyImage.Height*copyW/copyImage.Width;


        g.DrawImage(copyImage,width-copyW-10,hight-copyH-5,copyW,copyH);
        try 
        {
         bitmap.Save(catchPath+"123.jpg");  //这个文件夹有权限

        }
        catch (Exception e)
        {
         throw e;
        }

        bitmap.Dispose();

        newImage.Dispose();
        g.Dispose();
       }

     

    Message "GDI+ 中发生一般性错误。"

    Source "System.Drawing" 
    StackTrace  

    at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)

    at System.Drawing.Image.Save(String filename, ImageFormat format)

       at System.Drawing.Image.Save(String filename)  

    at KSI.KSI_Web.EnterpriseLisence.Drawing.DrawImg(Int32 width) in D:\worksharp\ksi\ksi_web\enterpriselisence\drawimg.aspx.cs:line 98"

    ----------------------------------------------------------------------------------------------------

    1.尽量使用 引用图片,避免直接加载物理图片

    eg://图片的地址
        string path=String.Format(@"D:共享文件夹EnterpriseLicences1123.jpg");

    Image newImage = Image.FromFile(path);    //取出图片

       g.DrawImage(newImage,0,0,width,hight);

    这种方式不是很可取,而且容易造成 GDI+错误

    2.VS03、05对GIF支持不是很完好!当你的程序执行较大操作的时候,且你会更新你的图片的时候,GDI+错误 偶尔、或者经常出现。

    我本人不知道解决方法。只能使用别的方式,加载GIF图片 或者不加载GIF图片

    注(您的代码比较严谨,不存在实质性的漏洞,加载释放都有,虽然位置不佳,但是依然可以达到 释放的目的)请你 更换GIF 图片 再 重新生成项目

    http://www.cnblogs.com/head/archive/2009/07/23/1529651.html

  • 相关阅读:
    【Azure 应用服务】在Azure App Service多实例的情况下,如何在应用中通过代码获取到实例名(Instance ID)呢?
    【Azure 应用服务】App Service For Windows 中如何设置代理实现前端静态文件和后端Java Spring Boot Jar包
    【Azure Developer】使用Azure Key Vault 的Key签名后,离线验证的一些参考资料
    【Azure Function】调试 VS Code Javascript Function本地不能运行,报错 Value cannot be null. (Parameter 'provider')问题
    【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(Xms512m Xmx1204m)?
    【Azure API 管理】APIM添加Logtoeventhub的策略后,一些相关APIM与Event Hub的问题
    【Azure API 管理】为调用APIM的请求启用Trace 调试APIM Policy的利器
    【Azure 事件中心】China Azure上是否有Kafka服务简答
    【Azure 应用服务】探索在Azure上设置禁止任何人访问App Service的默认域名(Default URL)
    【Azure 微服务】记一次错误的更新Service Fabric 证书而引发的集群崩溃而只能重建
  • 原文地址:https://www.cnblogs.com/iack/p/3704925.html
Copyright © 2020-2023  润新知