如何将SQL Server BLOB字符串转换为System.Drawing.Image

本文关键字:转换 System Drawing Image 字符串 BLOB SQL Server | 更新日期: 2023-09-27 18:26:33

如何将表示为字符串的BLOB转换为System.Drawing.Image类型?

背景

我将使用c#从csv文件中导入有关用户的信息以及他们的照片。我使用的专有SDK要求照片是System.Drawing.Image

下面是csv文件的示例。

surname firstname   photo                       
Blogs    Joe        0xFFD8FFE000104A46494600010101005F005F0000FFDB0043000D090A
                    

照片字段实际上有5k个字符长,是sql server数据库中BLOB字段值的直接导出。我们刚刚从数据库字段中获取了原始值,并将其导出到csv文件中。

下面的代码展示了我已经走了多远。cvsuser变量表示csv文件的一行。

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

然而,Image.FromStream()行抛出带有消息"的System.ArgumentException;参数无效"

问题

如何将表示为字符串的BLOB转换为System.Drawing.Image类型?

例如,我之前看到的示例会直接从数据库中获取blob,或者从文件中读取图像。

如何将SQL Server BLOB字符串转换为System.Drawing.Image

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

您列出的代码将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);

做这样的事情(根据之前给出的答案改编):

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

执行此操作可将string转换为byte[]:

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