10

这是我的问题。请耐心等待我做一点解释:

我正在将 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 像素值?

谢谢

4

2 回答 2

5

由于每个像素都表示为 16 位,从编程的角度来看,将 表示为长度的一半可能更方便,但这不是必需的。byte[]ushort[]

最佳解决方案取决于您希望如何使用缓冲区。

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

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

它使用输入坐标来确定原始偏移量byte[]并返回ushort由适当字节组成的 a。

如果 TIFF 存储数据大端且您的系统是小端,则您必须在转换之前反转字节顺序。一种方法是:

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

于 2013-02-13T15:34:42.793 回答
1

您需要循环执行:BitConverter.ToUInt16()占用 2 个字节,将它们转换为一个 ushort。

警告:正如 Eric 指出的那样,它存在字节顺序问题(它总是假定它正在执行的平台的字节顺序)。仅当您确定源字节流是在具有相同字节顺序的机器上生成时才使用 Bitconverter(对于 TIFF 图像,您可能无法假设它)。

您可以使用一些 LINQ... 例如这里有一个不错Chuncks功能。您可以将其用作:

rawBytes.Chunks(2).Select(b => BitConverter.ToUInt16(b)).toArray()
于 2013-02-13T15:37:15.913 回答