Dan Vogel
Dan Vogel

Reputation: 3938

"A generic error occurred in GDI+" when saving Bitmap object as jpeg, c#

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

Answers (6)

Drew Noakes
Drew Noakes

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

Thomas Jung
Thomas Jung

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

Thomas Jung
Thomas Jung

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

tekBlues
tekBlues

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

Jake Pearson
Jake Pearson

Reputation: 27717

I've seen this happen when the dimensions I was saving to weren't valid. Like a width of 0.

Upvotes: 0

Stilgar
Stilgar

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

Related Questions