Images need saving before they can be used …. who’da thunk it!

Having been tasked with adding images to the database I proceeded to write a simple test to allow me to get the underlying functionality correct so that I could roll out the changes across the system in confidence that it would all work and I could sleep soundly knowing that I hadn’t polluted our codebase with a load of code that doesn’t work.

So, I started by creating the table item in our Model assembly and added a test to see whether we can get the image into the database in byte array form. Simples.

The test took the structure of:

Test() {
// Arrange
GetTheImageFromTheFileSystem()
ConvertTheImageToByteArray()

// Act

SaveTheImageAsAByteArrayInTheDatabase()

// Assert
CheckThatTheImageReturnIsTheSameAsOriginalImage()
}

GetTheImageFromTheFileSystem() {
using (FileStream stream = new FileStream(@"C:Testtest.jpg", FileMode.Open, FileAccess.Read))
{
_image1 = Image.FromStream(stream);
}
}

public byte[] ConvertTheImageToByteArray(Image imageIn){
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, ImageFormat.Jpeg);
return ms.ToArray();
}

Notice that the getting of the image is in a different method to the converting of the image to a byte array.

Breaking it down meant that the first step was to get the image from the file system, easy peasy! Get that bit of code in place and move on to Converting the image to the desired format. No problem! A quick Google and we have this (http://www.codeproject.com/Articles/15460/C-Image-to-Byte-Array-and-Byte-Array-to-Image-Conv ) excellent article that gave me everything I needed.

Get that in there and quickly knock up the retrieval code and Robert’s your mother’s brother, we have a test that ….. Fails!

Ah …. “A Generic exception was thrown from GDI+” … helpful – thanks .NET!

A fair bit of intense googlage and my resident rubber duck (David) later led to the discovery that when you retrieve the image from the FileStream, you need to use it there and then (or save it in the relevant manner for later use). The problem happened to be that we were closing the FileStream that we had opened for retrieving the file and the image item didn’t hold on to the actual image data – it simply held onto the headers of the image file.

So a bit of refactoring to convert the byte array inside the fileStream that we used to retrieve the image and we have proof that the image can be saved to the database as a byte array! YAAAAAY!

private byte[] GetTheImageFromTheFileSystem() {
using (FileStream stream = new FileStream(@"C:Testtest.jpg", FileMode.Open, FileAccess.Read))
{
_image1 = Image.FromStream(stream);

MemoryStream ms = new MemoryStream();
imageIn.Save(ms, ImageFormat.Jpeg);
return ms.ToArray();
}
}

Now, back to the grindstone to do that actual functionality ( and tidy up the monstrosity I have left in the code whilst researching why this doesn’t work!)