Store image (jpg) in datatable

  • Thread starter Thread starter MS
  • Start date Start date
M

MS

I am storing an image in a datatable using the following code:

the dataset is created using oledb:
cmd = new OleDbCommand("SELECT * FROM StudentData " +

"WHERE RecordId=" + grdData.Rows[_RecordIdRowId].Cells["Value"].Text,
dbConn);

adapter = new OleDbDataAdapter(cmd);

dtStudent = new DataTable("Student");

adapter.Fill(dtStudent);

cmd = null;

adapter = null;

cmd = null;

adapter = null;

//define/add the column
DataColumn columname = dtStudent.Columns.Add("Image01", typeof(Image));

Put the image in the datatable
Bitmap bmp = new Bitmap(Common.gPic2LabPath + "Cropped\\" +
row["ImageName"].ToString().Trim());

dtStudent.Rows[0]["Image01" = bmp.Clone();

bmp.Dispose();


Dispose the datatable

dtStudent.Dispose();

If I try to rename the the image (on disk), I am told that another process
has it open.
Is there something else I need to do to release the image?
 
MS said:
[...]
Bitmap bmp = new Bitmap(Common.gPic2LabPath + "Cropped\\" +
row["ImageName"].ToString().Trim());

dtStudent.Rows[0]["Image01" = bmp.Clone();

bmp.Dispose();


Dispose the datatable

dtStudent.Dispose();

If I try to rename the the image (on disk), I am told that another process
has it open.
Is there something else I need to do to release the image?

Normally, disposing the original Bitmap instance would do that. I
haven't tried, but maybe the Clone() method copies _everything_,
including the dependency on the original file. You might try instead
copying the Bitmap instance by using the Bitmap(Bitmap) constructor
overload instead, and if that doesn't work, by just creating a new
Bitmap the same size and copying by using Graphics.FromImage() and
Graphics.DrawImage() to draw the original into the new.

If none of that works, post a concise-but-complete code example that not
only compiles but reliably demonstrates the problem.

Pete
 
MS said:
Put the image in the datatable
Bitmap bmp = new Bitmap(Common.gPic2LabPath + "Cropped\\" +
row["ImageName"].ToString().Trim());

dtStudent.Rows[0]["Image01" = bmp.Clone();

bmp.Dispose();


Dispose the datatable

dtStudent.Dispose();

If I try to rename the the image (on disk), I am told that another process
has it open.
Is there something else I need to do to release the image?

You create a Bitmap and then put it in the database without doing anything
else. I have to assume that the underlying column Image01 is some sort of
binary data type since I'm unaware of any DBMSes which have a "Graphic
Image" data type, so why not just create that column with type byte[] and
read the bytes in the file without turning it into a Bitmap? In other words,

DataColumn columname = dtStudent.Columns.Add("Image01", typeof(byte[]));

dtStudent.Rows[0]["Image01"] = File.ReadAllBytes(Common.gPic2LabPath +
"Cropped\\" + row["ImageName"].ToString().Trim());

(I also question naming a variable of type DataColumn "columnname". That
variable name suggests a string to me, not a whole DataColumn. I would have
called it "imageColumn" myself.)
 
If I try to rename the the image (on disk), I am told that another process
has it open.
Is there something else I need to do to release the image?

Don't use clone, it caused me problems for years until somebody in this
group pointed me in the right direction. You need to do something like this:

// Make a copy to avoid file locking/resource problems
imgReturn = new Bitmap(imgTemp, 16, 16);

In your case:
dtStudent.Rows[0]["Image01" = new Bitmap(bmp, 16, 16);

Then dispose the original (as you are doing):
bmp.Dispose();
 
Jeff is correct.
Normally,image data is read from or written to database as byte stream.
ImageColume should be defined as OleDbType.Binary.

Jeff Johnson said:
Put the image in the datatable
Bitmap bmp = new Bitmap(Common.gPic2LabPath + "Cropped\\" +
row["ImageName"].ToString().Trim());

dtStudent.Rows[0]["Image01" = bmp.Clone();

bmp.Dispose();


Dispose the datatable

dtStudent.Dispose();

If I try to rename the the image (on disk), I am told that another
process has it open.
Is there something else I need to do to release the image?

You create a Bitmap and then put it in the database without doing anything
else. I have to assume that the underlying column Image01 is some sort of
binary data type since I'm unaware of any DBMSes which have a "Graphic
Image" data type, so why not just create that column with type byte[] and
read the bytes in the file without turning it into a Bitmap? In other
words,

DataColumn columname = dtStudent.Columns.Add("Image01", typeof(byte[]));

dtStudent.Rows[0]["Image01"] = File.ReadAllBytes(Common.gPic2LabPath +
"Cropped\\" + row["ImageName"].ToString().Trim());

(I also question naming a variable of type DataColumn "columnname". That
variable name suggests a string to me, not a whole DataColumn. I would
have called it "imageColumn" myself.)
 
Back
Top