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.

4

2 回答 2

2

问题是十六进制编码字符串到字节数组之间的转换没有完成属性。

您列出的代码会将 blob 中的每个字符视为一个字节,因此“F”将被视为 0x46(大写 F 的 ascii 代码)。您想要做的是将每 2 个字符解码为一个字节 - 即 F0 = 240 等。

它假定字符串是偶数个字符。您还需要去掉“0x”前缀,因为这只是表明后面是数据的十六进制表示形式。

所以代替这个:

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);

做这样的事情(改编自之前给出的答案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);
于 2013-08-06T14:04:38.907 回答
1

这样做可以将您的转换stringbyte[]

System.Text.ASCIIEncoding  encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(strPhoto);
于 2013-08-06T14:15:05.843 回答