2012-09-17 26 views
6

GUI, C# ile basit bir görüntü işleme programı yapıyorum. Örneğin, HSV renk modelindeki görüntü renklerini değiştirmek, her bir pikseli RGB'ye dönüştürmek ve tekrar geri getirmek istiyorum.Görüntü pikseli pikselini WinAPI ile HIZLI YOLDA nasıl işleyebilirim?

Programım kullanıcı seçimine göre bazı resimler yükler ve bunu Grafik bağlamını kullanarak formun panelinden birinde gösterir. Daha sonra, kullanıcı bu resim ile kaydırma çubuklarını hareket ettirerek, düğmelere tıklayıp, bazı görüntü alanlarını seçerek vb. Bir şeyler yapabilir. Bunu yaptıktan sonra, gerçek zamanlı olarak tüm resmi piksel piksellerini değiştirmem gerekir. Yani, böyle bir şey yazmak:

for (int x = 0; x < imageWidth; x++) 
    for (int y = 0; y < imageHeight; y++) 
     Color c = g.GetPixel(x, y); 
     c = some_process_color_function_depending_on_user_controls(c); 
     g.SetPixel(x, y) 

Ve belleğe (ekrana değil) içinde Graphics ile çalışmak bile GetPixel fonksiyonları ve programım çok yavaş çalıştığı için SetPixel, böylece (ÇOK YAVAŞ çalışır, bunu profilli ve bu iki fonksiyonun programımı en fazla yavaşladığını açıkladı. Bu yüzden, kullanıcı kaydırma çubuğunu veya kontrol kutusunu işaretleyerek büyük resimleri birkaç kez işleyemiyorum.

Lütfen yardım edin! Programımı hızlı hale getirmek için ne yapabilirim? Grafikler veya programlama dilini değiştirmek için diğer üçüncü taraf kütüphanelerini kullanmayı kabul ediyorum!

+1

+1, güzel! – asawyer

cevap

7

Yep, Get/SetPixel işlevleri çok yavaş. Bunun yerine Bitmap.LockBits()/UnlockBits() kullanın. İşlenebilmesi için ham bit verilerini döndürür. msdn referanstan

: Bir profil oluşturucu kullanmak için

private void LockUnlockBitsExample(PaintEventArgs e) 
{ 

    // Create a new bitmap. 
    Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg"); 

    // Lock the bitmap's bits. 
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
    System.Drawing.Imaging.BitmapData bmpData = 
     bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, 
     bmp.PixelFormat); 

    // Get the address of the first line. 
    IntPtr ptr = bmpData.Scan0; 

    // Declare an array to hold the bytes of the bitmap. 
    // This code is specific to a bitmap with 24 bits per pixels. 
    int bytes = bmp.Width * bmp.Height * 3; 
    byte[] rgbValues = new byte[bytes]; 

    // Copy the RGB values into the array. 
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); 

    // Set every red value to 255. 
    for (int counter = 2; counter < rgbValues.Length; counter+=3) 
     rgbValues[counter] = 255; 

    // Copy the RGB values back to the bitmap 
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 

    // Unlock the bits. 
    bmp.UnlockBits(bmpData); 

    // Draw the modified image. 
    e.Graphics.DrawImage(bmp, 0, 150); 

} 
+0

Vay, kulağa hoş geliyor! Deneyeceğim. – Abzac

+0

@Abzac Ve bu çok yavaşsa XNA veya yönetilen directx'e bakabilirsiniz. – asawyer

+1

Güvenli olmayan kod bloklarını kullanarak daha fazla performans çekebilirsiniz (önemli bir tasarruf olup olmayacağını bilmeme rağmen). http://www.bobpowell.net/lockingbits.htm –

İlgili konular