【问题标题】:How to convert an SQL Server BLOB string to System.Drawing.Image?如何将 SQL Server BLOB 字符串转换为 System.Drawing.Image?
【发布时间】:2013-08-07 13:51:00
【问题描述】:

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

背景

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

以下是 csv 文件的示例。

surname firstname   photo                       
Blogs    Joe        0xFFD8FFE000104A46494600010101005F005F0000FFDB0043000D090A
                    

photo 字段实际上是 5k 字符长,是 sql server db 中 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 或从文件中读取图像。

【问题讨论】:

  • 这个 blob 字符串是 base64 编码的吗?
  • 我不这么认为。格式是 SQL Server 存储其 blob 的格式。我认为捕获照片的应用程序使用 SQL Server 的本机 blob 格式。

标签: c# string blob


【解决方案1】:

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

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

【讨论】:

  • 是的,问题是从十六进制编码字符串到字节数组的转换。这个例子对我有用。
【解决方案2】:

这样做可以将您的string 转换为byte[]

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

【讨论】:

  • 这不是byte[] bytes = new byte[strPhoto.Length * sizeof(char)]; System.Buffer.BlockCopy(strPhoto.ToCharArray(), 0, bytes, 0, bytes.Length); 在我已有的代码中所做的吗?
  • 您似乎没有获得全部数据。你试过我的代码了吗?
  • 是的,Image.FromStream(photostream) 抛出 ArgumentException,“参数无效”
  • 图片有多大?
  • 小于 10 kb, (
猜你喜欢
  • 2011-10-18
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 2017-07-07
相关资源
最近更新 更多