C# 字节[]到ushort[]

C# 字节[]到ushort[],c#,bytebuffer,data-conversion,ushort,C#,Bytebuffer,Data Conversion,Ushort,这是我的问题。请听我解释一下: 我正在将tiff图像读入缓冲区;我的tiff的每个像素由一个ushort(16位数据,非负)表示 我的图像大小是64*64=4096。因此,当我的tiff加载到缓冲区时,缓冲区长度为8192(是4096的两倍)。我猜这是因为在我的缓冲区中,计算机使用2个字节来存储单个像素值 我想得到任何特定像素的值,在这种情况下,我应该每2个字节合并一个ushort吗 例如:00000000111111->00000000111111 这是我的密码: public static

这是我的问题。请听我解释一下:

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

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

我想得到任何特定像素的值,在这种情况下,我应该每2个字节合并一个ushort吗

例如:00000000111111->00000000111111

这是我的密码:

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

            }
        }
publicstaticvoidloadtiff(字符串文件名,int-pxlIdx,ref-int-pxlValue)
{
使用(Tiff image=Tiff.Open(文件名,“r”))
{
if(image==null)
返回;
FieldValue[]值=image.GetField(TiffTag.IMAGEWIDTH);
int width=值[0]。ToInt();
byte[]buffer=新字节[image.StripSize()];
对于(int strip=0;strip
如何读取byte[]缓冲区以确保获得16位ushort像素值


谢谢

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

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

您可以同样轻松地定义一个helper方法

ushort GetImageDataAtLocation(int x, int y) 
{ 
    offset = y * HEIGHT + x;
    return BitConverter.ToUInt16(buffer, offset);
}
它使用输入坐标确定原始
字节[]
中的偏移量,并返回由适当字节组成的
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;
}
ushort GetImageDataAtLocation(int x,int y)
{ 
偏移=y*高度+x;
//交换机端号,例如TIFF为大端号,主机系统为小端号

ushort result=((ushort)buffer[0])您需要在循环中执行:
位转换器。ToUInt16()
需要2个字节,将它们转换为一个ushort

警告:正如Eric所指出的,它存在endianness问题(它总是假定它所执行的平台的endianness)。只有在您确定源字节流是在具有相同endianness的机器上生成的情况下,才使用Bitconverter(对于TIFF图像,您可能无法假定它)

您可以使用一些LINQ…例如,有一个很好的
Chuncks
函数。您可以将其用作:

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

不,它没有…它无法隐式地知道TIFF存储的数据是大的还是小的endian。它只是假设数据与平台的endian相同。NET在
上运行。数组中字节的顺序必须反映计算机系统架构的endian。哦,你是对的…我一直忘了它,我曾经在TIFF图像上工作……我编辑了我的答案,并对你的答案进行了升级,因为它更具吸引力complete@EricJ.在将其用于生产之前,我会对其进行测量。尽管如此,我还是经常惊讶于在某些情况下优化的程度是如此之高。特别是如果您将其用于流式处理。并且它具有PLINQ。读起来很好:)几乎在我遇到的每一个用例中,Linq都比传统的替代方案快得多(通常慢一点,但从来不会对整个用例如此重要).我怀疑图像处理是这样的:-)嗯…坏消息我必须做一个双循环,但这绝对是有用的信息。谢谢!虽然偏移量看起来是2的乘法,y实际上是(y-1),x也是一样。这取决于基于0或基于1的索引。