2013-02-13 27 views
9

Hier ist meine Frage. Bear mit mir eine kleine Erklärung:byte [] zu ushort []

Ich lese tiff Bild in den Puffer; Jedes Pixel meines Tiffs wird durch eine Ushort dargestellt (16 Bit Daten, nicht-negativ).

Meine Bildgröße ist 64 * 64 = 4096. Wenn mein TIFF in Puffer geladen wird, ist die Pufferlänge daher 8192 (doppelt so viel wie 4096). Ich denke, das liegt daran, dass der Computer in meinem Puffer 2 Byte zum Speichern eines einzelnen Pixelwerts verwendet.

Ich möchte den Wert für ein bestimmtes Pixel erhalten, in diesem Fall sollte ich alle 2 Bytes zu 1 ushort kombinieren?

Zum Beispiel: 00000000 11111111 -> 0000000011111111?

Hier ist mein Code:

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

      } 
     } 

Wie lese ich die byte [] Puffer, um sicherzustellen, dass ich die 16 Bit ushort Pixelwert erhalten kann?

Dank

Antwort

4

Da jedes Pixel als 16 Bits dargestellt wird, kann es bequeme von einer Programmier Perspektive sein, die als byte[]ushort[] der halben Länge darstellen, aber es ist nicht erforderlich.

Die beste Lösung hängt davon ab, wie Sie den Puffer verbrauchen möchten.

Sie könnte genauso leicht definiert eine Hilfsmethode

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

, die die Eingabe der Offset-Koordinaten verwendet, in den ursprünglichen byte[] und gibt ein ushort des entsprechenden Bytes zu bestimmen.

Wenn die TIFF Daten Big-Endian speichert und Ihr System Little-Endian ist, müssten Sie die Reihenfolge der Bytes vor der Konvertierung umkehren. Eine Möglichkeit, das zu tun ist:

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

Wenn Ihr Code immer auf Plattformen mit unterschiedlichen endianness laufen könnte (Intel und AMD sind beide Little-Endian) können Sie die endianness zur Laufzeit bestimmen kann mit

BitConverter.IsLittleEndian

Einzelheiten zu BitConverter finden http://msdn.microsoft.com/en-us/library/system.bitconverter.touint16.aspx

+0

Yup, ich denke, ich habe das Pixel, das ich will. Danke vielmals! –

+0

Obwohl der Offset scheint Multiplikation von 2, und y ist eigentlich (y-1), und das gleiche für x. Gut abhängig von dem 0 basierten oder 1 basierten Index. –

1

Sie müssen es in einer Schleife tun: BitConverter.ToUInt16() dauert 2 Bytes, um sie zu einem ushort konvertieren.

WARNUNG: wie Eric darauf hingewiesen hat, hat es Endianness-Probleme (es nimmt immer Endlichkeit der Plattform an, auf der es ausgeführt wird). Verwenden Sie Bitconverter nur, wenn Sie sicher sind, dass der Quellbyte-Stream auf einer Maschine mit derselben Endianität erzeugt wird (im Fall von TIFF-Bildern können Sie dies wahrscheinlich nicht annehmen).

Sie können einige LINQ verwenden ... zum Beispiel gibt es eine nette Chuncks Funktion here.Sie können es als verwenden:

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

Nein, es ist nicht ... es ist nicht implizit zu wissen, ob das TIFF die Daten Big- oder Little-Endian gespeichert hat. Es nimmt an, dass die Daten die gleiche Endianness wie die Plattform .NET auf "Die Reihenfolge der Bytes im Array muss die Endianess der Architektur des Computersystems widerspiegeln" http://msdn.microsoft.com/en-us/library /system.bitconverter.touint16.aspx –

+0

Linq beim Manipulieren von Bilddaten kann ein bisschen langsam sein. –

+0

@EricJ. Oh, du hast Recht ... Ich vergesse es immer wieder, und ich habe mit TIFF-Bildern gearbeitet, um ... Ich habe meine Antwort bearbeitet und deine Version aktualisiert, da sie vollständiger ist –