C#のポインタを使用して16bppを正しくアドレス指定する方法
質問
カメラのメタデータをビットマップにコピーしようとし、メタデータ内の各値が16ビット(またはUSHORT)として選択していると思ったと思ったと思いました。私が書いたコードは次のとおりです。
// 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を実行するとき。「PTRDESTINATION [x]=(ushort)* ptrmetaData; "for-loopsでメモリアクセス例外をスローします。240、半分の合計、行。
私は8bppでこれを使って解像度を下げ、それはうまくいったので、ここではすべきなのかわかりません。多分誰かが問題を見つけます。
既にありがとう
解決
ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;
.
DATA.STRIDE値は、USHORTSではなくバイト単位で表されます。そのため、ポインタは2倍になりますので、ビットマップ。Height / 2で爆弾します。あなたのループが壊れている、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;
}
}
. 所属していません StackOverflow