2013-02-13 7 views
9

ここは私の質問です。私に少し説明を与えてくれる:バイト[] to ushort []

私はバッファにtiffイメージを読み込んでいます。私のtiffの各ピクセルは、ushort(16ビットデータ、非負)で表されます。

私の画像サイズは64 * 64 = 4096です。私のtiffがバッファにロードされると、バッファの長さは8192(4096の2倍)になります。私の推測では、私のバッファーでは、コンピューターが2バイトを使用して1つのピクセル値を保管しているからです。

特定のピクセルの値を取得したいとします。この場合、2バイトごとに1時間を組み合わせる必要がありますか?

例:00000000 11111111 - > 0000000011111111?ここで

は私のコードです:

public static void LoadTIFF(string fileName, int pxlIdx, ref int pxlValue) 
     { 
      using (Tiff image = Tiff.Open(fileName, "r")) 
      { 
       if (image == null) 
        return; 

       FieldValue[] value = image.GetField(TiffTag.IMAGEWIDTH); 
       int width = value[0].ToInt(); 

       byte[] buffer = new byte[image.StripSize()]; 
       for (int strip = 0; strip < image.NumberOfStrips(); strip++) 
        image.ReadEncodedStrip(strip, buffer, 0, -1); 

       // do conversion here: 
       //ushort bufferHex = BitConverter.ToUInt16(buffer, 0);    

       image.Close(); 

      } 
     } 

私はバイト[]は、私がUSHORTピクセル値16ビットを得ることができることを保証するために、リード・バッファはどうすればよいですか?各画素は16ビットで表現されているので

おかげ

答えて

4

、それは半分の長さのushort[]としてbyte[]を表すプログラミングの観点からより便利かもしれないが、それは必須ではありません。

最適な解決策は、バッファをどのように消費するかによって異なります。

あなたは同じように簡単にヘルパーメソッド元byte[]のオフセットを決定するための座標入力を使用して適切なバイトから構成されるushortを返し

ushort GetImageDataAtLocation(int x, int y) 
{ 
    offset = y * HEIGHT + x; 
    return BitConverter.ToUInt16(buffer, offset); 
} 

を定義することができます。

TIFFにデータビッグエンディアンが保存され、システムがリトルエンディアンの場合、変換する前にバイトの順序を逆にする必要があります。それを行うための1つの方法は次のとおりです。

ushort GetImageDataAtLocation(int x, int y) 
{ 
    offset = y * HEIGHT + x; 
    // Switch endianness e.g. TIFF is big-endian, host system is little-endian 
    ushort result = ((ushort)buffer[0]) << 8 + buffer[1]; 
    return result; 
} 

あなたのコードは、これまで異なるエンディアンを持つプラットフォーム上で実行する可能性がある場合(IntelとAMDの両方がリトルエンディアンです)あなたは

BitConverter.IsLittleEndian

を使用して、実行時にエンディアンを決定することができますBitConverterの詳細については

、あなたがループの中でそれを行う必要があるhttp://msdn.microsoft.com/en-us/library/system.bitconverter.touint16.aspx

+0

うん、私は私が望むピクセルを持っていると思う。どうもありがとう! –

+0

オフセットは2倍のように見えますが、yは実際には(y-1)、xは同じです。 0ベースまたは1ベースのインデックスに依存します。 –

1

を参照してください。BitConverter.ToUInt16()は1 USHORTに変換し、2つのバイトを取ります。

警告:Ericが指摘したように、エンディアンの問題があります(エンディアンが常に実行されているプラ​​ットフォームのエンディアンを前提としています)。ビットエンコーダは、同じエンディアンのマシンでソースバイトストリームが生成されていることが確実な場合にのみ使用してください(TIFF画像の場合、それはおそらく想定できません)。

いくつかのLINQを使用することができます。例えば、Chuncksという便利な機能があります。hereです。

rawBytes.Chunks(2).Select(b => BitConverter.ToUInt16(b)).toArray() 
+0

いいえ、それは... TIFFがデータをビッグエンディアンかリトルエンディアンかを格納しているかどうかを暗黙のうちに知る方法はありません。それは、プラットフォームの.NETが動作しているのと同じエンディアンであると仮定しています。配列のバイト順序は、コンピュータシステムのアーキテクチャのエンディアンを反映している必要があります。http://msdn.microsoft.com/en-us/library /system.bitconverter.touint16.aspx –

+0

画像データを操作する際のLinqは少し遅いかもしれません。 –

+0

@EricJ。ああ、あなたは正しいです...私はそれを忘れてしまいました。私はTIFF画像を使って作業していました...私は自分の答えを編集し、より完全なのであなたのものを編集しました –