2012-05-27 4 views
7

MSDN ссылка: [1] http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx#Y1178Bitmap.Lockbits спутанность

Из ссылки он говорит, что первый аргумент будет «определяет часть Bitmap для блокировки», который я установил, чтобы быть меньшая часть Bitmap (Растровое изображение 500x500, мой прямоугольник равен (0,0,50,50)), однако возвращенный битмапДата имеет шаг 1500 (= 500 * 3), поэтому в основном каждое сканирование будет сканировать всю картинку по горизонтали. Однако то, что я хочу, это только верхняя левая часть 50x50 части растрового изображения.

Как это работает?

ответ

9

Шаг будет всегда иметь растровое изображение, но свойство 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); 

Так что, в основном, на самом деле просто заблокировав всю битовую карту, но дает вам указатель на левый верхний пиксель прямоугольника в битовой карте, и соответственно установите ширину и высоту сканирования.

+0

Спасибо. В этом есть смысл! –

+3

Нет гарантии, что шаг растрового изображения будет равен (ширина * байты на пиксель), таким образом, «var bpp = data.Stride/bitmap.Width;» (вы можете легко создать растровое изображение с другим шагом). Вы можете использовать (((bitmap.Pixelformat) >> 8) & 255), чтобы получить количество бит на пиксель, или (((bitmap.Pixelformat) >> 11) и 31) для байтов на пиксель. –

+0

Кроме того, если шаг важен для вас, вы можете предоставить свой собственный буфер и шаг с помощью ImageLockMode.UserInputBuffer. –

Смежные вопросы