步幅將始終爲完整位圖,但根據鎖定矩形的起點以及BitmapData的高度和寬度,Scan0屬性將會不同。
原因是,您仍然需要知道位圖的實際位寬,以遍歷行(添加步長到地址)。
一個簡單的方法去了解這將是:
var bitmap = new Bitmap(100, 100);
var data = bitmap.LockBits(new Rectangle(0, 0, 10, 10),
ImageLockMode.ReadWrite,
bitmap.PixelFormat);
var pt = (byte*)data.Scan0;
var bpp = data.Stride/bitmap.Width;
for (var y = 0; y < data.Height; y++)
{
// This is why real scan-width is important to have!
var row = pt + (y * data.Stride);
for (var x = 0; x < data.Width; x++)
{
var pixel = row + x * bpp;
for (var bit = 0; bit < bpp; bit++)
{
var pixelComponent = pixel[bit];
}
}
}
bitmap.UnlockBits(data);
所以它基本上是真的只是鎖定整個位圖,但給你一個指針到矩形的左上角的像素的位圖,並適當設置掃描的寬度和高度。
謝謝。這就說得通了! –
無法保證位圖的步幅將等於(每個像素的寬度*字節數),因此「var bpp = data.Stride/bitmap.Width;」是錯誤的(你可以輕鬆地創建一個不同的步幅位圖)。您可以使用((((bitmap.Pixelformat)>> 8)&255)來獲取每像素的位數,或((((bitmap.Pixelformat)>> 11)&31)。 –
另外,如果步幅對您很重要,您可以使用ImageLockMode.UserInputBuffer提供自己的緩衝區和步幅。 –