2008-10-10 28 views

cevap

47

Hız istiyorsanız, o zaman LockBits. Bob Powell tarafından iyi bir izlenim için buraya bakın. Sadece birkaç tane düzenlemek istiyorsanız, o zaman GetPixel/SetPixel istediğini yapmalısınız.

+0

güzel. Set/get pikselinin ötesine bakmayı hiç düşünmemiştim. Linkler için teşekkürler. – mattlant

+8

Bob Powell'ın size söylemediği şey, C# işaretçilerle gerçekten ilgilenmeniz gerekmediği. MSDN kütüphanesindeki LockBits'e bir göz atın, hafızayı, yöntemin güvensiz olarak işaretlenmediği yönetilen bir diziye kopyalayan bir örnek var ve bu nedenle uygulamanın güvensiz olması gerekmez :) – OregonGhost

+1

XNA kullanıcıları XBox360'a dikkat edin. NET CF, LockBits'in bulunduğu System.Drawing kitaplığını desteklemez. Bu yüzden DirectX'in yönetilmesi muhtemelen sizin tek seçeneğinizdir (teşekkürler Ash). –

4

System.Drawing.Bitmap, bir System.Drawing.Color yapısı döndüren bir GetPixel (int x, int y) genel yöntemine sahiptir. Bu yapıda, doğrudan değiştirebileceğiniz ve ardından Bitmap'inizde SetPixel (Color) öğesini çağırabileceğiniz R, G, B ve A bayt üyeleri bulunur.
Ne yazık ki, bu nispeten yavaş olacak, ancak C# içinde bunu yapmanın en kolay yolu. Tek tek piksellerle çok çalışıyorsanız ve performansın eksik olduğunu ve daha hızlı bir şeye ihtiyacınız varsa, LockBits'i kullanabilirsiniz. Bu renk derinliği ve tipi için bit yapısını anlamanız gerektiğinden, çok daha karmaşıktır. ve bitmap'in adımı ile çalışın ve ne yapmalısınız ... eğer gerekli bulursanız, iyi bir öğretici bulacağınızdan emin olun! Orada web'de birkaç var, Googling "C# LockBits" bir okumaya değer yarım düzine alacak.

14

Örnek kod yordamı (bunu basit birleştirme ve işlevsellik karşılaştırması için kullanıyorum. İki görüntüyü alır ve iki görüntü arasındaki farkları gri tonlama tonu düzeyinde gösteren üçüncü bir gri tonlamalı resim oluşturur. fark).

public static Bitmap Diff(Bitmap src1, Bitmap src2, int x1, int y1, int x2, int y2, int width, int height) 
{ 
    Bitmap diffBM = new Bitmap(width, height, PixelFormat.Format24bppRgb); 

    for (int y = 0; y < height; y++) 
    { 
     for (int x = 0; x < width; x++) 
     { 
      //Get Both Colours at the pixel point 
      Color col1 = src1.GetPixel(x1 + x, y1 + y); 
      Color col2 = src2.GetPixel(x2 + x, y2 + y); 

      // Get the difference RGB 
      int r = 0, g = 0, b = 0; 
      r = Math.Abs(col1.R - col2.R); 
      g = Math.Abs(col1.G - col2.G); 
      b = Math.Abs(col1.B - col2.B); 

      // Invert the difference average 
      int dif = 255 - ((r+g+b)/3); 

      // Create new grayscale RGB colour 
      Color newcol = Color.FromArgb(dif, dif, dif); 

      diffBM.SetPixel(x, y, newcol); 

     } 
    } 

    return diffBM; 
} 

Marc's post notlar LockBits ve bellekte resmi doğrudan değiştirmek için bu kullanarak. Performans endişesi varsa, yayınladığımdan ziyade buna bakmanızı öneririm. Teşekkürler Marc!

+1

sayesinde daha fazla oy gerekiyor! – geekido

+0

Muhtemelen birden çok kez bahsedildiği gibi, "GetPixel" ve "SetPixel" de oldukça yavaş. 'Marshal.Copy' ile birlikte' Bitmap.LockBits', aynı şeyi elde edebilir, ancak verileri pixel başına piksel yerine toplu olarak alır, bu da daha hızlı yüklenmesini sağlar. – Nyerguds

2

Performans önemliyse, LockBits'e başka bir alternatif DirectX tarafından yönetilir.

Daha fazla bilgi için önceki Yığın Taşması sorusuna bakın Rendering graphics in C#.

Lockbits gibi, güvensiz anahtar kelime/derleyici anahtarını kullanmanız gerekir, ancak yüksek performanslı piksel düzeyi erişimi elde edersiniz.

Ayrıca, normal Bitmap sınıfı ve PictureBox denetimiyle karşılaştırıldığında, DirectX backbuffering üzerinden daha yüksek performanslı ekran görüntüsü elde edersiniz.

+3

Yönetilen DirectX artık kullanımdan kaldırıldı. –