2013-02-13 15 views
9

Ecco la mia domanda. Resta con me dando una piccola spiegazione:byte [] in ushort []

Sto leggendo un'immagine tiff in buffer; Ogni pixel del mio tiff è rappresentato da un ushort (dati a 16 bit, non negativi).

La dimensione dell'immagine è 64 * 64 = 4096. Quando il mio tiff viene caricato nel buffer, la lunghezza del buffer è quindi 8192 (il doppio di 4096). Immagino sia perché nel mio buffer, il computer usa 2 byte per memorizzare un singolo valore di pixel.

Voglio ottenere il valore per ogni pixel particolare, in questo caso dovrei combinare ogni 2 byte in 1 ushort?

Ad esempio: 00000000 11111111 -> 0000000011111111?

Ecco il mio codice:

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

      } 
     } 

Come faccio a leggere il byte [] tampone per garantire che posso ottenere i 16 bit ushort valore di pixel?

Grazie

risposta

4

Poiché ogni pixel è rappresentato da 16 bit, può essere più conveniente da una prospettiva di programmazione per rappresentare la byte[] come ushort[] della metà della lunghezza, ma non è richiesto.

La soluzione migliore dipende da come si desidera utilizzare il buffer.

Si potrebbe facilmente definire un metodo di supporto

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

che utilizza coordinate di entrata per determinare l'offset in originale byte[] e restituisce una ushort composto dai byte appropriati.

Se il TIFF memorizza i dati big-endian e il sistema è little-endian, è necessario invertire l'ordine dei byte prima della conversione. Un modo per farlo è:

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

Se il codice potrebbe mai funzionare su piattaforme con differenti endian (Intel e AMD sono entrambe little-endian) è possibile determinare l'endianness in fase di esecuzione utilizzando

BitConverter.IsLittleEndian

per i dettagli sulla BitConverter, vedere http://msdn.microsoft.com/en-us/library/system.bitconverter.touint16.aspx

+0

Sì, penso di aver ottenuto il pixel che voglio. Grazie molto! –

+0

Anche se l'offset sembra moltiplicato per 2, y è effettivamente (y-1) e lo stesso per x. Bene a seconda dell'indice basato su 0 o 1. –

1

è necessario farlo in un ciclo: BitConverter.ToUInt16() prende 2 byte, convertirli in un ushort.

ATTENZIONE: come ha sottolineato Eric, ha problemi di endianità (presuppone sempre l'endianness della piattaforma su cui è in esecuzione). Utilizzare Bitconverter solo se si è certi che il flusso di byte di origine viene prodotto su una macchina con la stessa endianness (nel caso di immagini TIFF, probabilmente non lo si può assumere).

È possibile utilizzare alcuni LINQ ... ad esempio c'è una bella funzione Chunckshere.Puoi usarlo come:

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

No, non ... non ha modo di sapere implicitamente se il TIFF memorizza i dati big o little-endian. Suppone che i dati siano la stessa endianness della piattaforma .NET in esecuzione su 'L'ordine dei byte nell'array deve riflettere l'endianness dell'architettura del sistema del computer' http://msdn.microsoft.com/en-us/library /system.bitconverter.touint16.aspx –

+0

Linq durante la manipolazione dei dati di immagine potrebbe essere un po 'lento. –

+0

@EricJ. oh, hai ragione ... Continuo a dimenticarlo, e lavoravo su immagini TIFF per ... Ho modificato la mia risposta e ho aumentato la tua perché era più completa –