Как правильно адресовать 16bpp с указателями в C # - PullRequest
1 голос
/ 24 февраля 2012

Я пытаюсь скопировать метаданные камеры в растровое изображение, и вижу, что каждое значение в метаданных является 16-битным (или коротким). Я подумал, что было бы разумно отобразить его в 16-битном растровом битовом масштабе.Код, который я написал, выглядит следующим образом:

// Getting the metadata from the device
metaData = new DepthMetaData();
dataSource.GetMetaData(metaData);

// Setting up bitmap, rect and data to use pointer
Bitmap bitmap = new Bitmap(metaData.XRes, metaData.YRes, PixelFormat.Format16bppGrayScale);
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData data = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale);

// Pointer pointing to metadata
ushort* ptrMetaData = (ushort*)dataSource.DepthMapPtr.ToPointer();

lock(this)
{
    // Runs through the whole bitmap and assigns the entry in the metadata
    // to a pixel
    for (int y = 0; y < bitmap.Height; ++y)
    {
        ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;
        for (int x = 0; x < bitmap.Width; ++x, ++ptrMetaData)
        {
            ptrDestination[x] = (ushort)*ptrMetaData;
        }
    }
}

// Once done unlock the bitmap so that it can be read again
bitmap.UnlockBits(data);

При выполнении метаданных XRes = 640 и YRes = 480. Код генерирует исключение доступа к памяти в циклах for для "ptrDestination [x] = (ushort) * ptrMetaData;»после запуска хотя бы 240, половина общего количества строк.

Я использовал это с 8bpp, где я уменьшил разрешение, и оно работало хорошо, поэтому я не понимаю, почему это не должно быть здесь.Может быть, кто-то найдет проблему.

Спасибо уже

1 Ответ

2 голосов
/ 24 февраля 2012
    ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;

Значение data.Stride выражается в байтах, а не в ushorts.Таким образом, указатель отключен с коэффициентом 2, поэтому он взрывается по битовой карте. Высота / 2.Ваши циклы for не работают, поменяйте местами bitmap.Width и bitmap.Height.Ключевое слово lock не имеет особого смысла, вы обращаетесь к локальным данным потока, кроме dataSource.Исправить:

for (int y = 0; y < bitmap.Height; ++y)
{
    ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride / 2;
    for (int x = 0; x < bitmap.Width; ++x, ++ptrMetaData)
    {
        ptrDestination[x] = (ushort)*ptrMetaData;
    }
}
...