web-dev-qa-db-fra.com

Comment manipuler des images au niveau des pixels en C #

Comment manipuler des images au niveau des pixels en C #?

J'ai besoin de pouvoir lire/modifier séparément les valeurs RVB de chaque pixel bitmap.

Un exemple de code serait apprécié.

45
Kamil Zadora

Si vous voulez de la vitesse, alors LockBitsVoir ici pour une bonne procédure pas à pas par Bob Powell. Si vous voulez juste en éditer quelques-uns, alors GetPixel / SetPixel devrait faire ce que vous voulez.

50
Marc Gravell

Un exemple de routine de code (je l'utilise pour une simple fonctionnalité de fusion et de comparaison. Il prend deux images et produit une troisième image en niveaux de gris montrant les différences entre les deux images en tant que niveau de tonalité en niveaux de gris. Plus il est sombre, plus la différence est grande):

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

Post de Marc note LockBits et l'utilise pour modifier l'image directement en mémoire. Je suggérerais de regarder cela plutôt que ce que j'ai publié si la performance est un problème. Merci Marc!

15
mattlant

System.Drawing.Bitmap a une méthode publique GetPixel (int x, int y) qui renvoie une structure System.Drawing.Color. Cette structure contient des membres d'octets R, G, B et A, que vous pouvez modifier directement, puis appeler à nouveau SetPixel (Color) sur votre bitmap.
Malheureusement, cela va être relativement lent, mais c'est par la manière la plus simple de le faire en C #. Si vous travaillez beaucoup avec des pixels individuels et que vous constatez que les performances font défaut et que vous avez besoin de quelque chose de plus rapide, vous pouvez utiliser les LockBits ... C'est beaucoup plus compliqué cependant, car vous devez comprendre la structure des bits pour cette profondeur de couleur et ce type. , et travaillez avec la foulée du bitmap et quoi d'autre ... donc si vous trouvez que c'est nécessaire, assurez-vous de trouver un bon tutoriel! Il y en a plusieurs sur le Web, Googler "C # LockBits" vous en donnera une demi-douzaine qui valent la peine d'être lues.

5
Grank

Si les performances sont critiques, une autre alternative aux LockBits est gérée DirectX.

Voir la question précédente sur le débordement de pile Rendu des graphiques en C # pour plus d'informations.

Comme Lockbits, vous devrez utiliser le commutateur de mot clé/compilateur dangereux, mais vous aurez un accès au niveau des pixels haute performance.

Vous obtenez également un rendu d'écran plus performant via le backbuffering DirectX, par rapport à l'utilisation de la classe Bitmap normale et du contrôle PictureBox.

3
Ash