2012-05-27 8 views
7

MSDN Referenz: [1] http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx#Y1178Bitmap.Lockbits Verwirrung

von der Verbindung steht, dass das erste Argument wird „gibt der Abschnitt der Bitmap zu sperren“, das ich einen kleineren Teil der Bitmap sein (Bitmap ist 500x500, mein Rechteck ist (0,0,50,50)), aber die zurückgegebenen BitmapData haben eine Schrittweite von 1500 (= 500 * 3), also scannt grundsätzlich jeder Scan horizontal durch das ganze Bild. Was ich will, ist nur der obere linke 50x50 Teil der Bitmap.

Wie funktioniert das?

Antwort

9

Der Schritt wird immer von der vollständigen Bitmap sein, aber die Scan0-Eigenschaft unterscheidet sich je nach dem Startpunkt des Sperrrechtecks ​​sowie der Höhe und Breite der BitmapData.

Der Grund dafür ist, dass Sie immer noch die tatsächliche Bitbreite der Bitmap kennen müssen, um über die Zeilen zu iterieren (add stride to address).

Ein einfacher Weg zu gehen darüber sei:

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

So ist es im Grunde wirklich nur die ganze Bitmap sperren, aber Ihnen einen Zeiger auf den linken oberen Pixel des Rechtecks ​​in der Bitmap geben, und Einstellen der Breite und Höhe des Scans entsprechend.

+0

Danke. Das macht Sinn! –

+3

Es gibt keine Garantie, dass der Schritt der Bitmap gleich (Breite * Bytes pro Pixel) ist, also "var bpp = data.Stride/bitmap.Width;" ist falsch (Sie können leicht eine Bitmap mit einem anderen Schritt erstellen). Sie können (((Bitmap.Pixelformat) >> 8) & 255) verwenden, um die Anzahl der Bits pro Pixel oder (((Bitmap.Pixelformat) >> 11) & 31) für Bytes pro Pixel zu erhalten. –

+0

Wenn Schritt für Sie wichtig ist, können Sie auch Ihren eigenen Puffer und Schritt mit ImageLockMode.UserInputBuffer liefern. –