2009-08-04 17 views

cevap

25

Bu, her iki yöntemde de LockBits() ve GetPixel() kullanarak tam bir örnektir. LockBits() ile ilgili güven sorunlarının yanı sıra kılları kolayca alabilirsiniz.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 

namespace BitmapReader 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Try a small pic to be able to compare output, 
      //a big one to compare performance 
      System.Drawing.Bitmap b = new 
       System.Drawing.Bitmap(@"C:\Users\vinko\Pictures\Dibujo2.jpg"); 
      doSomethingWithBitmapSlow(b); 
      doSomethingWithBitmapFast(b); 
     } 

     public static void doSomethingWithBitmapSlow(System.Drawing.Bitmap bmp) 
     { 
      for (int x = 0; x < bmp.Width; x++) 
      { 
       for (int y = 0; y < bmp.Height; y++) 
       { 
        Color clr = bmp.GetPixel(x, y); 
        int red = clr.R; 
        int green = clr.G; 
        int blue = clr.B; 
        Console.WriteLine("Slow: " + red + " " 
             + green + " " + blue); 
       } 
      } 
     } 

     public static void doSomethingWithBitmapFast(System.Drawing.Bitmap bmp) 
     { 
      Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 

      System.Drawing.Imaging.BitmapData bmpData = 
       bmp.LockBits(rect, 
        System.Drawing.Imaging.ImageLockMode.ReadOnly, 
        bmp.PixelFormat); 

      IntPtr ptr = bmpData.Scan0; 

      int bytes = bmpData.Stride * bmp.Height; 
      byte[] rgbValues = new byte[bytes]; 

      System.Runtime.InteropServices.Marshal.Copy(ptr, 
          rgbValues, 0, bytes); 

      byte red = 0; 
      byte green = 0; 
      byte blue = 0; 

      for (int x = 0; x < bmp.Width; x++) 
      { 
       for (int y = 0; y < bmp.Height; y++) 
       { 
        //See the link above for an explanation 
        //of this calculation 
        int position = (y * bmpData.Stride) + (x * Image.GetPixelFormatSize(bmpData.PixelFormat)/8); 
        blue = rgbValues[position]; 
        green = rgbValues[position + 1]; 
        red = rgbValues[position + 2]; 
        Console.WriteLine("Fast: " + red + " " 
             + green + " " + blue); 
       } 
      } 
      bmp.UnlockBits(bmpData); 
     } 
    } 
} 
+1

Get/SetPixel kullanarak hiçbir görüntü işleme türünü uygulayamadım. Her zaman * yol * çok yavaş, hatta genel parlaklığı arttırmak gibi önemsiz işlemler için bile. –

+1

Resimleriniz büyük olduğunda her zaman çok yavaş. Simge büyüklüğünde görüntüler için bu mükemmel uygun :-) –

+0

Ah, evet, evet :-) –

9

Sen new Bitmap(filename) kullanarak resim yüklemek ve daha sonra art arda Bitmap.GetPixel kullanabilirsiniz. Bu çok yavaş ama basit. (Örnek için Vinko'nun yanıtına bakın.)

Performans önemliyse, Bitmap.LockBits ve güvenli olmayan kodu kullanmak isteyebilirsiniz. Açıkçası bu, çözümü (güven düzeyleri açısından) kullanabileceğiniz yer sayısını azaltır ve genellikle daha karmaşıktır - ancak lot daha hızlı olabilir.

+0

Vay. Bunu birkaç hafta önce aradım. Kesinlikle daha örnekte görünecek. Bağlantı için teşekkürler. – maxwellb

+0

Bu gerçekten çok daha karmaşık (ve gerçekten çok daha hızlı), görüntünün PixelFormatını göz önünde bulundurmanız, verilerin olup olmadığını kontrol etmemesi ve buna göre bazı değerleri atlamaması gerekiyor. MSDN örneği, bunlardan hiç bahsedilmediği için özellikle yararlı değildir. –

İlgili konular