2012-09-17 11 views
6

だから、私はGUI、C#で簡単な画像処理プログラムを作っています。たとえば、HSVカラーモデルで画像の色を変更し、各ピクセルをRGBから変換して元に戻したいとします。WinAPIを使用してピクセル単位でイメージを高速に処理する方法は?

私のプログラムは、ユーザーの選択によって画像を読み込んで、グラフィックスコンテキストを使ってフォームのパネルの1つに表示します。次に、ユーザーはスクロールバーの移動、ボタンのクリック、画像領域の選択などを行うことで、この画像で何かを行うことができます。だから、私は何か書く:

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) 

をそして、私は(ない画面上の)メモリにグラフィックスで作業しても、私のプログラムはとても遅い作品としてgetPixelメソッドととsetPixelは、とても(VERY SLOW働く機能し、私はそれをプロファイリングこの2つの機能が私のプログラムをほとんど遅くしていると説明した)。だから、ユーザーがスライダーを動かしたり、チェックボックスをチェックしたりするので、大きな画像を数回で処理することはできません。

助けてください!私のプログラムを速くするために私は何ができますか?私は他のサードパーティライブラリをグラフィックスやプログラミング言語の変更に使用することに同意しません。

+1

+1、素敵! – asawyer

答えて

7

はい、Get/SetPixel関数は非常に遅いです。代わりにBitmap.LockBits()/UnlockBits()を使用してください。あなたが操作するための生のビットデータを返します。 MSDNの参照から

:プロファイラを使用するための

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

うわー、いいね!私はそれを試してみます。 – Abzac

+0

@Abzacこれが遅すぎると、XNAまたは管理対象のDirectXを調べることができます。 – asawyer

+1

安全でないコードブロックを使用してパフォーマンスを絞り出すことができます(ただし、大幅な節約になるかどうかはわかりませんが)。 http://www.bobpowell.net/lockingbits.htm –

関連する問題