BMP to byte[] and back = GDI error ???

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I'm trying to convert an Image file to a byte[] array .
Later in my code I'm trying to create a new Image from this byte[] array as
a restored Image.
But when I try to save the restored Image to a Bitmap file I get a generic
DGI exception saying:
"A generic error occurred in GDI+".

Here is the code I'm using:

////// Loading a bitmap file to a byte[] array ////////////////////////
Bitmap bmpIn = Bitmap.FromFile("Picture.bmp", true) as Bitmap;
MemoryStream msIn = new MemoryStream();
bmpIn.Save(msIn,
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null);
msIn.Close();
byte[] buf = msIn.GetBuffer();

/////// Creating a new bitmap from the buf byte[] array /////////
Bitmap bmpOut;
MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
bmpOut = new Bitmap(msOut);
msOut.Close();
bmpOut.Save("ImageOut.bmp", System.Drawing.Imaging.ImageFormat.Bmp); //
ERROR: Throw the above exception !!!!


Can anybody tell what is the problem that causes the DGI error ?

Any help will be highly appreciated.
 
Sharon said:
I'm trying to convert an Image file to a byte[] array .
Later in my code I'm trying to create a new Image from this byte[] array as
a restored Image.
But when I try to save the restored Image to a Bitmap file I get a generic
DGI exception saying:
"A generic error occurred in GDI+".

Can anybody tell what is the problem that causes the DGI error ?

You've got two problems:
1) By using GetBuffer to start with, you'll end up with padding on the
end (unless you're very lucky). Use ToArray instead.

2) You're not rewinding the memory stream you're using when loading the
bitmap - you've passed the bitmap constructor a stream with no data to
read! Use msOut.Position = 0 before passing it in for reading.
 
Thanks Jon for your reply.

I have changed the code using your remarks as follow:

////// Loading a bitmap file to a byte[] array ////////////////////////
Bitmap bmpIn = Bitmap.FromFile("Picture.bmp", true) as Bitmap;
MemoryStream msIn = new MemoryStream();
bmpIn.Save(msIn,
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null);
msIn.Close();
byte[] buf = msIn.ToArray();

/////// Creating a new bitmap from the buf byte[] array /////////
Bitmap bmpOut;
MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
msOut.Position = 0;
bmpOut = new Bitmap(msOut);
msOut.Close();
bmpOut.Save("ImageOut.bmp", System.Drawing.Imaging.ImageFormat.Bmp); //
ERROR: Throw the above exception !!!!

But I'm still getting the same error.

Any idea why?
 
Sharon said:
Thanks Jon for your reply.

I have changed the code using your remarks as follow:

////// Loading a bitmap file to a byte[] array ////////////////////////
Bitmap bmpIn = Bitmap.FromFile("Picture.bmp", true) as Bitmap;
MemoryStream msIn = new MemoryStream();
bmpIn.Save(msIn,
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null);
msIn.Close();
byte[] buf = msIn.ToArray();

/////// Creating a new bitmap from the buf byte[] array /////////
Bitmap bmpOut;
MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
msOut.Position = 0;
bmpOut = new Bitmap(msOut);
msOut.Close();
bmpOut.Save("ImageOut.bmp", System.Drawing.Imaging.ImageFormat.Bmp); //
ERROR: Throw the above exception !!!!

But I'm still getting the same error.

Any idea why?

Not immediately. Are you sure it's the last line which is throwing the
exception, rather than the Bitmap constructor line?

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
Ok, here is the full post of the code:

// Loding the picture from a BMP file.
Bitmap bmpIn = Bitmap.FromFile(@"BlueLace.bmp", true) as Bitmap;
// Writing the image data to a MemoryStream.
MemoryStream msIn = new MemoryStream();
bmpIn.Save(msIn,
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null);
msIn.Close();
byte[] buf = msIn.ToArray();

MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
msOut.Position = 0;
Bitmap bmpOut = new Bitmap(msOut);
msOut.Close();
try
{
bmpOut.Save("ImageOut.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
catch( Exception exp )
{
MessageBox.Show(this, "Failed to save the image to file.\n\n" +
exp.Message + "\n\nTrace: \n" + exp.StackTrace,
"Bitmap Save Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
System.Diagnostics.Process.Start("ImageOut.bmp");
 
OK, I think I see what you mean. So here is the code again:

namespace BmpTest
{
using System;
using System.Drawing;
using System.IO;

class MyClass
{
[STAThread]
static void Main(string[] args)
{
Bitmap bmpIn = Bitmap.FromFile(@"C:\WINDOWS\Blue Lace 16.bmp",
true) as Bitmap;
MemoryStream msIn = new MemoryStream();
bmpIn.Save(msIn,
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null);
msIn.Close();

byte[] buf = msIn.ToArray();

MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
msOut.Position = 0;
Bitmap bmpOut = new Bitmap(msOut);
msOut.Close();

try
{
bmpOut.Save("ImageOut.bmp",
System.Drawing.Imaging.ImageFormat.Bmp);
}
catch( Exception exp )
{
Console.WriteLine("Failed to save the image to file.\n" +
exp.Message + "\n\nTrace: \n" + exp.StackTrace);
Console.ReadLine();
return;
}
System.Diagnostics.Process.Start("ImageOut.bmp");
}
}
}
 
Hi Sharon,

You are closing the MemoryStream before the Bitmap is saved.
Move msOut.Close() down a few lines

MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
msOut.Position = 0;
Bitmap bmpOut = new Bitmap(msOut);
try
{
bmpOut.Save("ImageOut.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
catch( Exception exp )
{
MessageBox.Show(this, "Failed to save the image to file.\n\n" +
exp.Message + "\n\nTrace: \n" + exp.StackTrace,
"Bitmap Save Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
System.Diagnostics.Process.Start("ImageOut.bmp");
msOut.Close();
 
Amazingly it works.

I'm amazed because the msOut MemoryStream is not used when the Bitmap bmpOut
is doing the saving to a file.
 
For some reason the Bitmap object keeps a lock on its source. If you use Image.FromFile the file is locked until you dispose of the Bitmap. Apparantly the same goes for Stream sources. Not sure why it does this.
 
Back
Top