&引用;GDI+;中发生一般性错误&引用;将位图对象保存为jpeg时,c#

&引用;GDI+;中发生一般性错误&引用;将位图对象保存为jpeg时,c#,c#,.net,bitmap,jpeg,C#,.net,Bitmap,Jpeg,我有一个ushort像素数据数组(16位灰度值),我正试图将其保存为jpeg图像。但是,我的代码在Save命令下崩溃,出现了“GDI+中发生的一般错误”。我想不出怎么解决这个问题。我保存到的目录是由我的应用程序创建的,我将其他文件写入其中;所以我知道这不是权限问题。这可能是数据损坏问题吗?在将ushort数据导入位图对象的步骤中,我是否做错了什么?因为我有ushort数据,我发现花了一些功夫才弄清楚如何将它放入位图对象,我可能做错了 这是我的密码: Bitmap img = new Bitmap

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

这是我的密码:

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

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

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

我看到在保存到的维度无效时会发生这种情况。宽度是0。

恐怕这和灰度/JPG有关。我不知道JPEG是否支持灰度


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

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

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

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

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

您正在使用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); 

不幸的是,GDI+不支持正确的
PixelFormat.Format16bppGrayScale
。我一直在研究这个长期存在的问题,还没有找到解决办法


现代的方法似乎是在
System.Windows.Media

中使用较新的WPF API,你是在一个单独的线程中运行它吗?是的,我是在一个单独的线程中运行它的。你认为这就是问题所在吗?这似乎就是问题所在。当我将像素格式更改为某种颜色格式时,它不会崩溃。但是,生成的jpeg图像不是彩色的,细节丢失。我的意思是“是彩色的”不是“不是”jpeg支持8位灰度。位图没有8位灰度像素格式。我应该如何转换16位灰度值,以便在仍然表示相同图像的情况下将其保存为jpeg格式?只需将UInt16值除以256即可获得字节。由于16位灰度值被用作其他内容,因此质量会降低。因此,16位不是用作一个值,而是用作3个值。