为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

GDI+中发生一般性错误

2018-04-27 13页 doc 34KB 130阅读

用户头像

is_180829

暂无简介

举报
GDI+中发生一般性错误GDI+中发生一般性错误 “GDI+中发生一般性错误” 的终极解决办法~ 我遇到的情况: 在编写Chem.NET的时候要保存图片,我先用openFileDialog打开图片文件,然后用saveFileDialog保存文件时就出现了 “GDI+中发生一般性错误”,我当时就想到是打开的文件还没有释放出来,于是用openFileDialog1.Dispose()来释放,可是没有成功。同样从一个MemorySream 实例打开一个Image后,立即关闭了这个流,结果在Image.Save时也会发生这种错误。我“摆渡”了很久都是遇...
GDI+中发生一般性错误
GDI+中发生一般性错误 “GDI+中发生一般性错误” 的终极解决办法~ 我遇到的情况: 在编写Chem.NET的时候要保存图片,我先用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( //将第一个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文件资源 } } 通过以上的读取文件,在保存的时候就不会出现错误了。 ******************************************************************************** ******* 保存Bitmap到流中引发“GDI+中发生一般性错误” -------------------------------------------------------------------------------- --------- 在.NET中进行图像很容易处理引发“GDI+中发生一般性错误”,最近我就碰到了一次。其场 景如下: SQL Server数据库中有一CoverImage字段,其类型为varbinary,用于保存图像的二进制 数据。 我需要在一个Windows Form应用程序中使用PictureBox(名为picCoverImage)从本地硬盘 加载图片文件显示,然后,再将图像本身塞入到数据库中。 我采用的方法是将PictureBox的Image属性引用的图像对象先转换为字节数组,再使用LINQ to SQL更新回数据库: //„„ if (picCoverImage.Image != null) { using (MemoryStream mem = new MemoryStream()) { picCoverImage.Image.Save(mem, picCoverImage.Image.RawFormat); //book是LINQ to SQL生成的数据实体对象 book.CoverImage = new Binary(mem.ToArray()); } } //„„ 然而,很奇怪的是,上述代码在往数据库中新加图像时是成功的,而一旦要修改时 picCoverImage.Image.Save(...)一句总引发“GDI+中发生一般性错误”。 仔细对比“新建”与“修改”的不同: “新建”时,我是使用OpenFileDialog选择文件,然后设置PictureBox的ImageLocation属性装载并显示图片,上述代码运行正常。 “修改”时,我从数据库中取出图像数据,使用以下方法在PictureBox中显示图片: //显示图像 if (book.CoverImage != null) { using (MemoryStream mem = new MemoryStream(book.CoverImage.ToArray())) { picCoverImage.Image = new Bitmap(mem); } } 现在,再次尝试将PictureBox中的Image写入到内存流中,picCoverImage.Image.Save(...)一句就引发“GDI+中发生一般性错误”。 百思不得其解。估计是PictureBox内部对Image引用的图像进行了特殊处理,也没时间去用Reflector等工具去深挖细掘,最后是用这个笨方法解决的: 克隆一个新的Bitmap对象。 修 //更新图像 if (picCoverImage.Image != null) { using (MemoryStream mem = new MemoryStream()) { //克隆Bitmap对象 Bitmap bmp = new Bitmap(picCoverImage.Image); bmp.Save(mem, picCoverImage.Image.RawFormat); book.CoverImage = new Binary(mem.ToArray()); bmp.Dispose(); } } 修正后的代码工作正常。 本文来自CSDN博客,转载请标明出处: ******************************************************************************** ********* 注:第一次写博客,把自己遇到的问题和收集的资料记录在博客上。 在开发.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() 方法以获取有关二 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文件资源 } } 通过以上的读取文件,在保存的时候就不会出现错误了。 ******************************************************************************** ************* 我写的一个生成缩略图程序, 生成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:\共享文件夹\EnterpriseLicences\1\123.jpg"); //保存水印图片的文件夹 string catchPath=Server.MapPath(@"..\temp\cache\"); 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(@"..\Images\EnterpriseLisence\Logos.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:\共享文件夹\EnterpriseLicences\1\123.jpg"); Image newImage = Image.FromFile(path); //取出图片 g.Dr 这种方式不是很可取,而且容易造成 GDI+错误 2.VS03、05对GIF支持不是很完好~当你的程序执行较大操作的时候,且你会更新你的图片的时候,GDI+错误 偶尔、或者经常出现。 我本人不知道解决方法。只能使用别的方式,加载GIF图片 或者不加载GIF图片 注(您的代码比较严谨,不存在实质性的漏洞,加载释放都有,虽然位置不佳,但是依然可以达到 释放的目的)请你 更换GIF 图片 再 重新生成项目
/
本文档为【GDI+中发生一般性错误】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索