【问题标题】:Reloading Img to memorystream causes a [ A generic error occurred in GDI+ ]将 Img 重新加载到 memorystream 会导致 [A generic error occurred in GDI+]
【发布时间】:2020-11-04 15:00:06
【问题描述】:

当我尝试更新数据库中的记录图像时遇到问题。

目前使用的工作流程如下:

  1. 用户使用 FilaDialog 将图像加载到图片框。

         DialogResult path = openFileDialog1.ShowDialog();
         if (path == DialogResult.OK)
         {
             pictureBox.Image = new Bitmap(openFileDialog1.FileName);
             pictureBox.Refresh();
         }
    
  2. 在用户完成插入剩余字段并尝试保存后,从 PictureBox 加载图像并保存到数据库。

     Image img = PictureBox.Image;
     byte[] photo_aray = null;
             using (MemoryStream ms = new MemoryStream())
              {
                     img.Save(ms, ImageFormat.Jpeg);
                     photo_aray = new byte[ms.Length];
                     ms.Position = 0;
                     ms.Read(photo_aray, 0, photo_aray.Length);
              }
    

到目前为止一切都很好,但是当我尝试更新以下图像时会出现问题:

  1. 用户从列表中选择记录,事件加载记录信息,图像加载到图片框。

  2. 在用户完成更新剩余字段并尝试保存图像后,从 PictureBox 加载图像并使用上面编写的相同逻辑保存到数据库,但对 SQL 查询进行了一些更改。

     Image img = PictureBox.Image;
     byte[] photo_aray = null;
             using (MemoryStream ms = new MemoryStream())
              {
                     img.Save(ms, ImageFormat.Jpeg); // BREAKING POINT
                     photo_aray = new byte[ms.Length];
                     ms.Position = 0;
                     ms.Read(photo_aray, 0, photo_aray.Length);
              }
    

每次用户尝试更新时,都会显示以下错误消息:

GDI+.:: 在 System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) 中发生一般错误 at System.Drawing.Image.Save(Stream流,ImageFormat格式)

请注意,如果用户更改图像或只是使用 Filedialog 选择相同的图像,则不会发生错误。

感谢任何帮助。

****** 编辑 #1 *********

只是为了澄清,

  1. 记录首先从数据库加载到绑定到列表的 RecordsList 对象中。
  2. 当用户选择某条记录时,图像会从选定记录加载到图片框。
  3. 如果没有对图片进行任何更改,则图片会从图片框加载到上述逻辑。

【问题讨论】:

  • 用户从列表中选择Record,事件加载Record信息,图像加载到PictureBox。:这里发生了什么?顺便说一句,你不需要那个photo_aray,你可以直接返回ms.ToArray()。将 Image 分配回 PictureBox 时,尽量不要释放 MemoryStream。
  • @Jimi 记录信息存储在数据库中,并显示在带有自定义绑定数据源的列表框中。因此,每当用户选择一条记录时,我都可以访问包含所有信息的对象。至于 photo_array,我进一步使用它将图像存储到数据库。请注意,记录首先从数据库加载到RecordsList 对象中,当用户选择某条记录时,Image 从RecordsList 对象加载到PictureBox。感谢您的帮助。
  • 这就是我所问的,将字节数组从数据库加载到 PictureBox 的部分。如果你需要那个photo_aray(你实际上不需要它,你可以将该代码移动到一个返回数组的方法中),你可以写photo_aray = ms.ToArray()并删除Read()调用,这是无用的,也容易出错。
  • 我假设您在从数据库加载字节数组时执行相同的操作:使用 MemoryStream 并使用 using 语句处理它。尽量不要那样做。此外,您在保存图像时强制使用 JPEG 格式:您应该使用 Image.RawFormat(它为您提供图像的原始格式)。
  • @Jimi 不会处理 MemoryStream 超载内存吗?

标签: c# winforms memorystream


【解决方案1】:

感谢@Jimi 先生,我已经设法解决了这个问题。

正如他亲切地指出的那样,我需要在保存对象后处理内存流。

所以我的代码是这样编辑的:

Image img = PictureBox.Image;
byte[] photo_aray = null;
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Jpeg); 
photo_aray = new byte[ms.Length];
ms.Position = 0;
ms.Read(photo_aray, 0, photo_aray.Length);
//
//
//SQL UPDATE HERE
//
//
ms.Close();
ms.Dispose();

谢谢!

【讨论】:

    猜你喜欢
    • 2017-06-21
    • 1970-01-01
    • 2019-09-11
    • 2021-02-13
    • 2021-08-01
    • 2022-12-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    相关资源
    最近更新 更多