Como resolver adequadamente 16bpp com ponteiros em C#
Pergunta
Eu estou tentando copiar os metadados da câmera em um Bitmap, e ver como cada valor de metadados é um 16bit (ou ushort) eu pensei que seria sensato para exibi-lo em uma 16bpp garyscale de mapa de bits.O código que eu escrevi é como segue:
// 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);
Ao executar os Metadados do XRes = 640 e YRes = 480.O código lança uma exceção de acesso à memória no para-ciclos em "ptrDestination[x] = (ushort)*ptrMetaData;" depois de apenas executar o que a 240, metade do total de linhas.
Eu usei isso com 8bpp onde eu reduzido a resolução e funcionou muito bem, então eu não vejo por que ele não deve aqui.Talvez alguém encontra o problema.
Graças já
Solução
ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;
Os dados.Passada valor é expresso em bytes, não ushorts.Para que o ponteiro está desativado por um fator de 2 para ele bombas em bitmap.Altura/2.Seus ciclos são quebradas, trocar de mapa de bits.Largura e de bitmap.A altura.O bloqueio de palavras-chave não faz muito sentido aqui, você está acessando thread-local de dados, outros de origem de dados.Correção:
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;
}
}