Reputation: 598
I'm very new to this stuff of saving images to the DB, and even when I thought it was very straight forward, it wasn't. What I'm trying to do is read and image file from the same computer in any format, display it in a picture box, and then convert the image to bytes to save it in the DB. Until now, I can display the image in the picture box, but I can't convert the image to bytes. Here's my code:
private void DisplayImage()
{
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
try
{
Stream file;
if ((archivo = openFileDialog.OpenFile()) != null)
{
using (file)
{
pictureBox.Image = Image.FromStream(file);
}
}
}
catch (Exception ex)
{
...
}
}
}
That's a simple method that just displays the image in the picture box. The real problem is with the following method:
public static byte[] ConvertImageToBytes(Image image)
{
if (image != null)
{
MemoryStream ms = new MemoryStream();
using (ms)
{
image.Save(ms, ImageFormat.Bmp);
byte[] bytes = ms.ToArray();
return bytes;
}
}
else
{
return null;
}
}
When it tries to save the image to the memory stream, I get the error:
System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.
Any ideas on what's happening?
Upvotes: 4
Views: 5460
Reputation: 1
private void btnSave_Click(object sender, EventArgs e) { if (!DoValidation()) return; item.ItemName = txtItemName.Text; item.ItemDescription = txtItemDescription.Text; item.Quaintity = Convert.ToInt32(txtQuaintity.Text); item.Price = Convert.ToInt32(txtPrice.Text); item.Thumbna = (byte)Convert.ToInt32(picitem.Text);
Upvotes: -1
Reputation: 1
The problem with this is that stream must be open during the lifetime of of the image otherwise will fail.
One solution that worked for me is just to create a copy of the image like this:
using (var ms = new MemoryStream(bytes))
{
_image = new Bitmap(Image.FromStream(ms));
}
Upvotes: 0
Reputation: 598
It may be stupid to answer my own question, but I just found out that if I want to convert the Image object to bytes, I have to leave the original stream open. I saw this issue in another page I can't quite remember, and I tested it by leaving the stream open and it's true. So the format wasn't the problem. But I will take the advice of all of you and store the images in a separate directory. Thanks for your help guys!
Upvotes: 1
Reputation: 10681
Cant you simply Read the file and load it to a byte[] using the File class:
byte[] imgData = System.IO.File.ReadAllBytes(@"C:\My Pic\Myfile.jpg");
You can pick the image path from your Open Dialog box.
Upvotes: 2
Reputation: 62096
You should use the RawFormat property of the original image as a parameter to the Save method, not default to a Bitmap. This will avoid image format type errors. eg:
image.Save(ms, image.RawFormat);
ms.Position = 0;
byte [] bytes=ms.ToArray();
I'd advise actually saving images to the file-system and simply storing the file path (preferably relative) in the database.
BLOBs (ie images etc) in a database cannot be indexed, are often stored in a secondary, slower access database area and will quickly blow out the size of the database (slower backups etc).
Upvotes: 3
Reputation: 122624
That particular exception generally means that you are trying to save the image as the wrong format. In your code you specify ImageFormat.Bmp
- is it actually a bitmap image, or did you perhaps load it from a JPEG or PNG? Attempting to save as a different format from the one you loaded will fail with ExternalException
, as specified in the documentation.
Incidentally, I don't recommend storing images in a database and I believe most people here will agree. Databases may be able to handle this task but they are not optimized for it, and you end up hurting the performance of both your database and your application. Unless you are using SQL Server 2008 FILESTREAM
columns, it is more efficient to store images on the file system.
Upvotes: 1