这是我的问题。请跟我说一点解释:
我正在读取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();
}
}
如何读取byte []缓冲区以确保我能获得16位ushort像素值?
由于
答案 0 :(得分:5)
由于每个像素都表示为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;
}
如果您的代码可能在具有不同字节顺序的平台上运行(Intel和AMD都是little-endian),则可以使用
确定运行时的字节顺序。有关BitConverter的详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.bitconverter.touint16.aspx
答案 1 :(得分:1)
您需要在循环中执行:BitConverter.ToUInt16()
需要2个字节,将它们转换为一个ushort。
警告:正如Eric指出的那样,它有字节序问题(它总是假定它正在执行的平台的字节顺序)。仅当您确定源字节流是在具有相同字节顺序的计算机上生成时才使用Bitconverter(如果是TIFF图像,您可能无法假设它。)
您可以使用一些LINQ ...例如,有一个很好的Chuncks
函数here。您可以将其用作:
rawBytes.Chunks(2).Select(b => BitConverter.ToUInt16(b)).toArray()