Filtres et manipulation d'images en utilisant lockbits et des pointeurs


Description

Le but de cet exemple est de montrer comment manipuler une image, en accédant aux données directement en mémoire via la fonction "Lockbits" des Bitmaps.
J'y inclus aussi un filtre d'Eclaircissement (Brightness) comme exemple , à vous de vous servir de votre imagination pour en trouver d'autre ;]
(ou si vous voulez pas chercher envoyez moi un mail ^^")

Source / Exemple :


//namespace
using System.Drawing;
using System.Drawing.Imaging;

//Cette fonction nous retourne une Image eclaircie
private static Image Brightness(Image ImageOrigine)
{
       //On créer donc un nouveau bitmap pour garder notre original intacte
       Bitmap bmp = new Bitmap(ImageOrigine,ImageOrigine.Width,ImageOrigine.Height);
       //C'est dans un BitmapData qu'on utilise Lockbits
       //On fait donc un Lockbits des données de notre Bitmap ....
       BitmapData bmpData = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
       //Maintenant on collecte certaines informations ...
       int scanline = bmpData.Stride;   //le stride(appelé aussi scanline) est la largeur d'une rangée de pixels dans l'image;
       IntPtr scan0 = bmpData.Scan0; // le Scan0 nous indique où se trouve le 1er pixel en mémoire 

       unsafe // comme on utilise des pointeurs il faut indiquer qu'on code en "unsafe" mode  
       {
                // "p" sera donc notre pointeur 
                byte* p = (byte*)(void*)scan0;
                //on peut aussi écrire  "byte* p = (byte*)scan0.ToPointer();"
                
                //quelques variables nécéssaires
                int val;
                int nOffset = scanline-bmp.Width*3;
                int nWidth = bmp.Width*3;   //*3 parce qu'on travail des couleurs sur3 bytes "RGB"
                
                //C'est durant la prochaine boucle "for" qu'on travail nos pixels
                for(int  y = 0 ; y < bmp.Height ; ++y)
                {
                        for( int x = 0 ; x < nWidth ; ++x)
                        {
                               //on ajoute 50 (par ex.) pour rendre plus claire mais -50 , vous l'aurez deviné rendra l'image plus sombre !
                               val = (int)p[0]+50;
                               //on verifie que les valeurs ne dépasse pas 255 
                               if(val>255)val=255;
                               p[0]=(byte)val;
                               //on a donc augmenté la valeur du premier byte pour ce pixel , on passe au suivant
                               ++p; 
                        }
                         p+=nOffset;
                }
       }
        //notre modif effectuée on "relache" les données
        bmp.UnlockBits(bmpData);

        //On retourne l'image transformée :D
        return (Image)bmp;
}

Conclusion :


note : dans le traitement d'images, la rapidité est très importante , c'est une des raisons pour laquelle les pointeurs sont toujours utilisés dans ce domaine.
(aussi , vous noterez le "++i" au lieu de "i++" , en effet ++i est plus rapide à executer que "i++" en mémoire).

C'est ma premiere source de ce type , il est possible que j'ai fais quelques erreurs , si c'est le cas je m en excuse d'avance !!

Bon courage !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.