Reputation: 3938
I have an array of ushort pixel data (16-bit grayscale values), and I am trying to save it as a jpeg image. However my code is crashing at the Save command with "A generic error occurred in GDI+". I can't figure out how to fix this. The directory I am saving to is created by my application and I write other files to it; so I know it's not a permissions problem. Is it maybe a data corruption problem? Am I doing something wrong in the steps to get the ushort data into the Bitmap object? Because I have ushort data I found it took some effort to figure out how to get it into the Bitmap object, and I am possibly doing it wrong.
Here is my code:
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);
This whole thing has become very frustrating. Please help?!
Upvotes: 2
Views: 7032
Reputation: 310802
Unfortunately, GDI+ doesn't support PixelFormat.Format16bppGrayScale
properly. I've been researching this long-standing issue and haven't found a solution.
It seems that the modern day approach is to use the newer WPF APIs in System.Windows.Media
.
Upvotes: 1
Reputation: 727
Regarding your comment about image quality (I would have responded as a comment, but it loses the code formatting):
You are saving with the default settings for JPEG export. You can create your own EncoderParameters instance with a higher quality setting:
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);
Upvotes: 1
Reputation: 727
I have found that any bitmap that I had drawn on, no matter which way, had an occasional problem with being saved as JPEG (with the exception you are seeing). What helped was to clone the image first:
img.Clone(); // or:
img.Clone(rectangle, img.PixelFormat);
Maybe by doing this you can also try to change the pixel format, because I also assume, just like tekBlues, that there may be issues with greyscale.
Upvotes: 1
Reputation: 5793
I'm, afraid it has something to do with the grayscale / JPG. I don't know if JPEG supports grayscales.
I would try declaring the bitmap as a normal color one. And testing.
Upvotes: 3
Reputation: 27717
I've seen this happen when the dimensions I was saving to weren't valid. Like a width of 0.
Upvotes: 0
Reputation: 23551
I am willing to bet that this is permissions problem. GDI+ is native component and I believe it requires different permissions than regular file saving or something like this. Is this ASP.NET app? If so make sure you give permissions to the IIS process for that folder.
Upvotes: 0