步幅将始终为完整位图,但根据锁定矩形的起点以及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提供自己的缓冲区和步幅。 –