7

そこで、GUI、C# で簡単な画像処理プログラムを作成します。たとえば、HSV カラー モデルの画像の色を変更して、各ピクセルを RGB から変換し、再び元に戻したいとします。

私のプログラムは、ユーザーの選択によっていくつかの画像をロードし、グラフィックスコンテキストを使用してフォームのパネルの 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 は非常に遅く動作します (そのため、プログラムの動作が非常に遅いため、プロファイルを作成し、これら 2 つの関数がせいぜいプログラムの速度を低下させるだけであると説明しました) )。そのため、ユーザーがスライダーを動かしたり、チェックボックスをチェックしたりすると、大きな画像を数時間で処理できません。

助けてください!プログラムを高速化するにはどうすればよいですか? グラフィック用に他のサードパーティ製ライブラリを使用したり、プログラミング言語を変更したりすることに同意しません!

4

1 に答える 1

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

}
于 2012-09-17T21:32:46.280 に答える