Байт [] в 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 см. 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()