2013-02-13 71 views
9

这是我的问题。忍受我给一点点解释:byte [] to ushort []

我正在阅读tiff图像到缓冲区;我的tiff的每个像素都由一个ushort(16位数据,非负)表示。

我的图像大小是64 * 64 = 4096.当我的tiff被加载到缓冲区时,缓冲区长度因此是8192(两倍于4096)。我想这是因为在我的缓冲区中,计算机使用2个字节来存储单个像素值。

我想获得任何特定像素的值,在这种情况下,我应该结合每2个字节1 ushort?

例如: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(); 

      } 
     } 

我如何读取字节[]缓冲区,以确保我能得到16位USHORT像素值?

由于

回答

4

由于每个像素被表示为16个比特,它可以是更方便从编程的角度来表示byte[]为一半的长度的ushort[],但它不是必需的。

最好的解决方案取决于你想如何使用缓冲区。

你可以很容易地定义一个辅助方法

ushort GetImageDataAtLocation(int x, int y) 
{ 
    offset = y * HEIGHT + x; 
    return BitConverter.ToUInt16(buffer, offset); 
} 
使用输入坐标,确定在原 byte[]偏移,并返回一个适当的字节组成 ushort

如果TIFF存储big-endian数据并且您的系统是little-endian,则必须在转换之前反转字节的顺序。要做到这一点的方法之一是:

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

如果你的代码可能永远在一个有着不同顺序的平台上运行(英特尔和AMD都是小端),你可以使用在运行时确定的存储方式

BitConverter.IsLittleEndian

有关BitConverter详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.bitconverter.touint16.aspx

+0

是的,我想我得到了我想要的像素。非常感谢! – 2013-02-13 17:10:04

+0

尽管偏移看起来是2的乘法,而y实际上是(y-1),并且对于x也是一样的。那么取决于基于0或1的索引。 – 2013-02-21 01:13:34

1

你需要做的是在一个循环:BitConverter.ToUInt16()占用2个字节,并将其转换为一个USHORT。

警告:正如Eric指出的那样,它存在字节序问题(它始终假定它正在执行的平台的字节顺序)。只有在确定源字节流是在具有相同字节序的机器上生成的情况下(如果是TIFF图像,则可能无法假定它),请使用Bitconverter。

您可能会使用一些LINQ ...例如有一个不错的Chuncks函数here。你可以使用它:

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

不,它没有......它无法隐式知道TIFF是否存储了大数据还是小数据。它的绝对值假设数据和运行的平台的数据是相同的字节序排列'数组中的字节顺序必须反映计算机系统体系结构的字节顺序http://msdn.microsoft.com/en-us/library /system.bitconverter.touint16.aspx – 2013-02-13 15:39:04

+0

Linq在处理图像数据时可能会稍微慢一些。 – 2013-02-13 15:42:35

+0

@EricJ。哦,你是对的...我一直忘记它,而我曾经在TIFF图像上工作......我编辑了我的答案,并向上投票,因为它更完整 – 2013-02-13 15:43:45