1

How can I convert a BLOB represented as a string to a System.Drawing.Image type?

Background

I am going to import information about users together with their photo from a csv file using c#. The proprietary SDK that I use requires the photo to be a System.Drawing.Image

Below is an example of the csv file.

surname firstname   photo                       
Blogs    Joe        0xFFD8FFE000104A46494600010101005F005F0000FFDB0043000D090A
                    

The photo field is actually 5k chars long and is a direct export of the BLOB field value in the sql server db. We have just taken the raw value from the database field and exported it to the csv file.

Below is the code that demonstrates how far I have got. The cvsuser variable represents one row of the csv file.

// We need to convert the photo from a string to a byte array
string strPhoto = null;
strPhoto = csvuser.photo; // The string that represents the BLOB
byte[] bytes = new byte[strPhoto.Length * sizeof(char)];
System.Buffer.BlockCopy(strPhoto.ToCharArray(), 0, bytes, 0, bytes.Length);
                   
// Then we create a memory stream that holds the image
MemoryStream photostream = new MemoryStream( bytes );

// Then we can create a System.Drawing.Image by using the Memory stream
var photo = Image.FromStream(photostream);

However, the Image.FromStream() line throws a System.ArgumentException with the message "Parameter is not valid."

Question

How can I convert the BLOB represented as a string to a System.Drawing.Image type?

The examples I have seen previously would, for example, fetch the blob straight from the database or reading the image from a file.

2
  • is this blob string base64 encoded ? Commented Aug 6, 2013 at 14:03
  • I don't think so. The format is the format that SQL Server stores its blob in. I think the application that captures the photo uses the native blob format of SQL Server. Commented Aug 6, 2013 at 14:08

2 Answers 2

2

The issue is that the conversion between the hex-encoded string to byte array isn't being done property.

The code you listed will treat each of the chars in the blob as a byte, so an 'F' will be treated as 0x46 (the ascii code for a capital F). What you want to do is de-code each 2 characters as a single byte - i.e. F0 = 240 etc.

It assumes the string is an even number of characters. You'll also need to strip off the '0x' prefix, as that's just an indicator that what follows is a hexadecimal representation of the data.

So instead of this:

strPhoto = csvuser.photo; // The string that represents the BLOB
byte[] bytes = new byte[strPhoto.Length * sizeof(char)];
System.Buffer.BlockCopy(strPhoto.ToCharArray(), 0, bytes, 0, bytes.Length);

Do something like this (adapted from previous answer given here):

      strPhoto = csvuser.photo; // The string that represents the BLOB

      //remove first 2 chars (the '0x')
      strPhoto = strPhoto.Remove(0, 2);

      //convert hex-string to bytes:
      int NumberChars = strPhoto.Length/2;
      byte[] bytes = new byte[NumberChars];
      using (StringReader sr = new StringReader(strPhoto)){
            for (int i = 0; i < NumberChars; i++)
               bytes[i] = Convert.ToByte(new string(new char[2]{(char)sr.Read(), (char)sr.Read()}), 16);
      }

      // Then we create a memory stream that holds the image
      MemoryStream photostream = new MemoryStream( bytes );

      // Then we can create a System.Drawing.Image by using the Memory stream
      var photo = Image.FromStream(photostream);
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, the issue was the conversion from the Hex-encoded string to the byte array.This example did the trick for me.
1

Do this to convert your string to byte[]:

System.Text.ASCIIEncoding  encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(strPhoto);

5 Comments

Isn't that what byte[] bytes = new byte[strPhoto.Length * sizeof(char)]; System.Buffer.BlockCopy(strPhoto.ToCharArray(), 0, bytes, 0, bytes.Length); is doing in the code that I already have?
It looks like you're not getting the whole data. Did you try my code?
Yes, Image.FromStream(photostream) throws an ArgumentException, "Parameter is not valid"
How big is the image?
less than 10 kb, ( < 10kb )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.