1

文字列として表された BLOB を System.Drawing.Image 型に変換するにはどうすればよいですか?

バックグラウンド

c# を使用して、csv ファイルから写真と共にユーザーに関する情報をインポートします。私が使用する独自の SDK では、写真が System.Drawing.Image である必要があります。

以下は、csv ファイルの例です。

surname firstname   photo                       
Blogs    Joe        0xFFD8FFE000104A46494600010101005F005F0000FFDB0043000D090A
                    

写真フィールドは実際には 5k 文字の長さで、SQL サーバー データベースの BLOB フィールド値を直接エクスポートしたものです。データベース フィールドから生の値を取得し、csv ファイルにエクスポートしました。

以下は、私がどこまで到達したかを示すコードです。cvsuser変数は csv ファイルの 1 行を表します。

// 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 を直接取得したり、ファイルから画像を読み取ったりしていました。

4

2 に答える 2

2

問題は、16 進数でエンコードされた文字列からバイト配列への変換がプロパティで行われていないことです。

リストしたコードは、ブロブ内の各文字をバイトとして扱うため、「F」は 0x46 (大文字の F の ASCII コード) として扱われます。やりたいことは、各 2 文字を 1 バイトとしてデコードすることです。つまり、F0 = 240 などです。

文字列が偶数の文字であると想定しています。また、'0x' プレフィックスを削除する必要があります。これは、後に続くものがデータの 16 進数表現であることを示すためです。

したがって、これの代わりに:

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);
于 2013-08-06T14:04:38.907 に答える