2012-05-27 11 views
7

referencia MSDN: [1] http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx#Y1178Bitmap.LockBits confusión

Desde el enlace que dice que el primer argumento se "especifica la porción del mapa de bits para bloquear" la cual di a ser una parte más pequeña de la Bitmap (Bitmap es 500x500, mi rectángulo es (0,0,50,50)), sin embargo, el bitmapData devuelto tiene una zancada de 1500 (= 500 * 3), por lo que básicamente todos los escaneos seguirán escaneando toda la imagen horizontalmente. Sin embargo, lo que quiero es solo la parte superior izquierda 50x50 del mapa de bits.

¿Cómo funciona esto?

Respuesta

9

La zancada siempre será del mapa de bits completo, pero la propiedad Scan0 será diferente según el punto de inicio del rectángulo de bloqueo, así como la altura y el ancho de BitmapData.

La razón de esto es que aún necesitará conocer el ancho de bit real del mapa de bits, para iterar sobre las filas (agregar paso a la dirección).

Una forma sencilla de hacerlo sería:

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); 

Por lo que es, básicamente, en realidad sólo bloqueando todo el mapa de bits, pero que le da un puntero al píxel superior izquierdo del rectángulo en el mapa de bits, y estableciendo el ancho y alto del escaneo apropiadamente.

+0

Gracias. ¡Eso tiene sentido! –

+3

No hay garantía de que la zancada del mapa de bits sea igual a (ancho * bytes por píxel), por lo tanto, "var bpp = data.Stride/bitmap.Width;" es incorrecto (puede crear fácilmente un mapa de bits con una zancada diferente). Puede usar ((((bitmap.Pixelformat) >> 8) y 255) para obtener el número de bits por píxel, o (((bitmap.Pixelformat) >> 11) y 31) para los bytes por píxel. –

+0

Además, si la zancada es importante para usted, puede suministrar su propio búfer y caminar con ImageLockMode.UserInputBuffer. –