Байт [] в ushort[]

Вот мой вопрос Потерпи немного объяснений:

Я читаю TIFF изображение в буфер; Каждый пиксель моего tiff представлен короткой строкой (данные 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?

Спасибо

2 ответа

Решение

Поскольку каждый пиксель представлен в виде 16 битов, может быть более удобным с точки зрения программирования представлять byte[] как ushort[] половины длины, но это не обязательно.

Лучшее решение зависит от того, как вы хотите использовать буфер.

Вы можете так же легко определить вспомогательный метод

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

который использует входные координаты для определения смещения в оригинале byte[] и возвращает ushort состоит из соответствующих байтов.

Если 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;
}

Если ваш код может когда-либо выполняться на платформах с разным порядком байтов (Intel и AMD оба имеют порядок байтов), вы можете определить порядок байтов во время выполнения, используя

BitConverter.IsLittleEndian

Для получения дополнительной информации о BitConverter см. Http://msdn.microsoft.com/en-us/library/system.bitconverter.touint16.aspx

Вы должны сделать это в цикле: BitConverter.ToUInt16() занимает 2 байта, преобразовать их в один ushort.

ВНИМАНИЕ: как указал Эрик, у него есть проблемы с порядком байтов (он всегда подразумевает порядок байтов платформы, на которой он выполняется). Используйте Bitconverter, только если вы уверены, что поток исходных байтов генерируется на машине с тем же порядком байтов (в случае изображений TIFF вы, вероятно, не можете принять это).

Вы можете использовать некоторые LINQ... например, есть хороший Chuncks функционировать здесь. Вы можете использовать его как:

rawBytes.Chunks(2).Select(b => BitConverter.ToUInt16(b)).toArray()
Другие вопросы по тегам