2012-05-27 15 views
7

MSDN referans: [1] bağlantısından http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx#Y1178Bitmap.Lockbits karışıklık

ilk argüman ben Bitmap daha küçük bir parçası (olarak ayarlanır hangi "Bitmap bölümü kilitlemek için belirtir" söylüyor Bitmap 500x500, benim dikdörtgendir (0,0,50,50)), ancak döndürülmüş BitmapData 1500 (= 500 * 3) 'lik bir adımdır, bu nedenle temel olarak her tarama yatay olarak tüm resmi taramaya devam edecektir. Ancak, istediğim sadece bitmap'in sol üst 50x50 kısmı.

Bu nasıl çalışır?

cevap

9

Adım, her zaman tam bit eşlemde olacak, ancak Scan0 özelliği, kilit dikdörtgeninin başlangıç ​​noktasına ve BitmapData'nın Genişliği ve Genişliğine göre farklı olacaktır.

Bunun nedeni, satırların üzerinde yineleme yapmak için bitmap'in gerçek bit genişliğini hâlâ bilmeniz gerekmesidir (adrese ekleme ekleyin).

olurdu hakkında gitmek için basit bir yolu:

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

Yani temelde gerçekten sadece bütün bitmap kilitleme, ancak bitmap'te dikdörtgenin sol üst piksele size bir işaretçi veriyor, ve tarama genişliğini ve yüksekliğini uygun şekilde ayarlama.

+0

Teşekkürler. Bu mantıklı! –

+3

Bitmap'in adımının eşit olacağını (piksel başına genişlik * bayt), dolayısıyla "var bpp = data.Stride/bitmap.Width;" yanlış (farklı bir adımla kolayca bir bitmap oluşturabilirsiniz). Piksel başına bit sayısını elde etmek için (((bitmap.Pixelformat) >> 8) & 255) veya piksel başına bayt için (((bitmap.Pixelformat) >> 11) & 31) kullanabilirsiniz. –

+0

Ayrıca, adım sizin için önemliyse, kendi arabelleğinizi temin edebilir ve ImageLockMode.UserInputBuffer ile devam edebilirsiniz. –