it-swarm.com.de

Bearbeiten von Bildern auf Pixelebene in C #

Wie bearbeite ich Bilder auf Pixelebene in C #?

Ich muss in der Lage sein, jeden Bitmap-Pixel-RGB-Wert separat zu lesen/zu ändern.

Ein Codebeispiel wäre willkommen.

45
Kamil Zadora

Wenn Sie Geschwindigkeit wollen, dann LockBitsHier finden Sie eine gute Anleitung von Bob Powell. Wenn Sie nur ein paar bearbeiten möchten, sollte GetPixel / SetPixel tun, was Sie wollen.

50
Marc Gravell

Beispielcode-Routine (Ich verwende diese Routine zum einfachen Zusammenführen und Vergleichen. Es werden zwei Bilder aufgenommen und ein drittes Graustufenbild erstellt, in dem die Unterschiede zwischen den beiden Bildern als Graustufentonpegel dargestellt sind. Je dunkler, desto stärker der Unterschied.):

    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 merkt sich LockBits und ändert damit das Bild direkt im Speicher. Ich würde vorschlagen, dass Sie sich das ansehen und nicht das, was ich gepostet habe, wenn Leistung ein Problem darstellt. Vielen Dank, Marc!

15
mattlant

System.Drawing.Bitmap verfügt über eine öffentliche Methode GetPixel (int x, int y), die eine System.Drawing.Color-Struktur zurückgibt. Diese Struktur enthält die Bytemitglieder R, G, B und A, die Sie direkt ändern und dann erneut SetPixel (Color) in Ihrer Bitmap aufrufen können.
Leider wird das relativ langsam sein, aber es ist der einfachste Weg, dies in C # zu tun. Wenn Sie häufig mit einzelnen Pixeln arbeiten und feststellen, dass die Leistung unzureichend ist und Sie etwas Schnelleres benötigen, können Sie LockBits verwenden. Dies ist jedoch viel komplizierter, da Sie die Bitstruktur für diese Farbtiefe und diesen Farbtyp verstehen müssen , und arbeite mit den Schritten der Bitmap und was nicht ... also, wenn du es für notwendig hältst, finde ein gutes Tutorial! Es gibt einige im Internet, mit Googeln mit "C # LockBits" erhalten Sie ein halbes Dutzend, die es wert sind, gelesen zu werden.

5
Grank

Wenn die Leistung kritisch ist, ist DirectX eine weitere Alternative zu LockBits.

Weitere Informationen finden Sie in der früheren Frage zum Stapelüberlauf Rendern von Grafiken in C #.

Wie bei Lockbits müssen Sie den unsicheren Schlüsselwort-/Compiler-Schalter verwenden, erhalten jedoch Zugriff auf Pixelebene mit hoher Leistung.

Durch das DirectX-Backbuffering erhalten Sie im Vergleich zur Verwendung der normalen Bitmap-Klasse und des PictureBox-Steuerelements auch eine leistungsfähigere Bildschirmwiedergabe.

3
Ash