【问题标题】:"A generic error occurred in GDI+" when saving Bitmap object as jpeg, c#将位图对象保存为 jpeg、c# 时出现“GDI+ 中发生一般错误”
【发布时间】:2009-06-15 19:24:14
【问题描述】:

我有一组超短像素数据(16 位灰度值),我正在尝试将其保存为 jpeg 图像。但是,我的代码在“GDI+ 中发生一般错误”的保存命令中崩溃。我不知道如何解决这个问题。我要保存到的目录是由我的应用程序创建的,我将其他文件写入其中;所以我知道这不是权限问题。这可能是数据损坏问题吗?我在将 ushort 数据放入 Bitmap 对象的步骤中做错了吗?因为我有 ushort 数据,我发现要弄清楚如何将其放入 Bitmap 对象需要付出一些努力,而且我可能做错了。

这是我的代码:

Bitmap img = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
Rectangle rect = new Rectangle(0,0, width, height);
BitmapData picData = img.LockBits(rect, ImageLockMode.ReadWrite, img.PixelFormat);
IntPtr pixelStartAddress = picData.Scan0;

WriteableBitmap pic = new WriteableBitmap(width, height, 96.0, 96.0, System.Windows.Media.PixelFormats.Gray16, null);

int stride = (thumb.XSize * pic.Format.BitsPerPixel + 7) / 8;
pic.WritePixels(new System.Windows.Int32Rect(0, 0, width, height), dataArray, stride, 0);  

pic.CopyPixels(new System.Windows.Int32Rect(0,0,thumb.XSize, thumb.YSize),pixelStartAddress, dataArray.Length * sizeof(ushort), stride);

img.UnlockBits(picData);
img.Save(path, ImageFormat.Jpeg);

整个事情变得非常令人沮丧。请帮忙?!

【问题讨论】:

  • 你是在单独的线程中运行它吗?
  • 是的,我确实在单独的线程中运行它。你认为这是问题所在吗?

标签: c# .net bitmap jpeg


【解决方案1】:

我担心它与灰度/JPG有关。不知道JPEG是否支持灰度。

我会尝试将位图声明为普通颜色。和测试。

【讨论】:

  • 这似乎是问题所在。当我将 PixelFormat 更改为某种颜色格式时,它不会崩溃。但是,生成的 jpeg 图像没有颜色,并且丢失了细节。
  • 我的意思是“有颜色”而不是“不是”
  • JPEG 支持 8 位灰度。
  • 位图没有 8 位灰度 PixelFormat。我应该如何转换我的 16 位灰度值,以便它们可以保存为 jpeg,同时仍然代表相同的图像?
  • 只需将 UInt16 值除以 256 即可得到字节。
【解决方案2】:

我发现我绘制的任何位图,无论采用哪种方式,在保存为 JPEG 时偶尔都会出现问题(您看到的例外情况除外)。帮助的是首先克隆图像:

img.Clone(); // or:
img.Clone(rectangle, img.PixelFormat);

也许通过这样做,您也可以尝试更改像素格式,因为我也假设,就像 tekBlues 一样,可能存在灰度问题。

【讨论】:

    【解决方案3】:

    关于您对图像质量的评论(我会以评论的形式回复,但它会丢失代码格式):

    您正在使用 JPEG 导出的默认设置进行保存。您可以使用更高质量设置创建自己的 EncoderParameters 实例:

    var encParams = new EncoderParameters(1);
    var encParams.Param[0] = new EncoderParameter(Encoder.Quality, 91L);
    // get jpegEncoder by looping through ImageCodecInfo.GetImageEncoders())
    image.Save("path to file", jpegEncoder, encParams); 
    

    【讨论】:

    • 质量下降,因为 16 位灰度值被用作其他东西。所以 16 位不是一个值,而是 3 个值。
    【解决方案4】:

    很遗憾,GDI+ 不能正确支持PixelFormat.Format16bppGrayScale。我一直在研究这个长期存在的问题,但没有找到解决方案。

    现代方法似乎是在System.Windows.Media 中使用较新的 WPF API。

    【讨论】:

      【解决方案5】:

      我敢打赌这是权限问题。 GDI+ 是本机组件,我相信它需要不同于常规文件保存或类似的权限。这是 ASP.NET 应用程序吗?如果是这样,请确保您授予该文件夹的 IIS 进程权限。

      【讨论】:

        【解决方案6】:

        我已经看到当我保存到的维度无效时会发生这种情况。像宽度为 0。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-02
          • 2013-09-26
          • 1970-01-01
          相关资源
          最近更新 更多