web-dev-qa-db-fra.com

Convertir une image en niveaux de gris

Existe-t-il un moyen de convertir une image au format 16 bits par pixel en niveaux de gris, plutôt que de régler chacune des composantes r, g et b sur la luminance. J'ai actuellement un bmp de fichier.

Bitmap c = new Bitmap("filename");

Je veux un Bitmap d, qui est la version en niveaux de gris de c. Je vois un constructeur qui inclut System.Drawing.Imaging.PixelFormat, mais je ne comprends pas comment l'utiliser. Je débute dans le traitement d'images et dans les bibliothèques C # pertinentes, mais j'ai une expérience modérée de C # lui-même.

Toute aide, référence à une source en ligne, conseil ou suggestion sera la bienvenue.

EDIT: d est la version en niveaux de gris de c.

53
0fnt

"Je veux un bitmap d, en niveaux de gris. Je vois un constructeur qui inclut System.Drawing.Imaging.PixelFormat, mais je ne comprends pas comment l'utiliser."

Voici comment faire cela

Bitmap grayScaleBP = new 
         System.Drawing.Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);

EDIT: Pour convertir en niveaux de gris

             Bitmap c = new Bitmap("fromFile");
             Bitmap d;
             int x, y;

             // Loop through the images pixels to reset color.
             for (x = 0; x < c.Width; x++)
             {
                 for (y = 0; y < c.Height; y++)
                 {
                     Color pixelColor = c.GetPixel(x, y);
                     Color newColor = Color.FromArgb(pixelColor.R, 0, 0);
                     c.SetPixel(x, y, newColor); // Now greyscale
                 }
             }
            d = c;   // d is grayscale version of c  

Version plus rapide de switchonthecode suivez le lien pour une analyse complète:

public static Bitmap MakeGrayscale3(Bitmap original)
{
   //create a blank bitmap the same size as original
   Bitmap newBitmap = new Bitmap(original.Width, original.Height);

   //get a graphics object from the new image
   Graphics g = Graphics.FromImage(newBitmap);

   //create the grayscale ColorMatrix
   ColorMatrix colorMatrix = new ColorMatrix(
      new float[][] 
      {
         new float[] {.3f, .3f, .3f, 0, 0},
         new float[] {.59f, .59f, .59f, 0, 0},
         new float[] {.11f, .11f, .11f, 0, 0},
         new float[] {0, 0, 0, 1, 0},
         new float[] {0, 0, 0, 0, 1}
      });

   //create some image attributes
   ImageAttributes attributes = new ImageAttributes();

   //set the color matrix attribute
   attributes.SetColorMatrix(colorMatrix);

   //draw the original image on the new image
   //using the grayscale color matrix
   g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
      0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);

   //dispose the Graphics object
   g.Dispose();
   return newBitmap;
}
66
Asad Butt
Bitmap d = new Bitmap(c.Width, c.Height);

for (int i = 0; i < c.Width; i++)
{
    for (int x = 0; x < c.Height; x++)
    {
        Color oc = c.GetPixel(i, x);
        int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
        Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale);
        d.SetPixel(i, x, nc);
    }
}

De cette façon, il conserve également le canal alpha.
Prendre plaisir.

35
Vercas

Il y a une méthode statique dans ToolStripRenderer class, nommée CreateDisabledImage. Son utilisation est aussi simple que:

Bitmap c = new Bitmap("filename");
Image d = ToolStripRenderer.CreateDisabledImage(c);

Il utilise une matrice légèrement différente de celle de la réponse acceptée et la multiplie en outre par une transparence de valeur 0,7; l'effet est donc légèrement différent de l'échelle de gris. Toutefois, si vous souhaitez que votre image soit grisée, c'est la plus simple. meilleure solution.

18
Szybki

Aucun des exemples ci-dessus ne crée d'images bitmap 8 bits (8 bpp). Certains logiciels, tels que le traitement d'images, ne prennent en charge que 8bpp. Malheureusement, les bibliothèques MS .NET n'ont pas de solution. Le format PixelFormat.Format8bppIndexed semble prometteur, mais après de nombreuses tentatives, je n'ai pas réussi à le faire fonctionner.

Pour créer un véritable fichier bitmap 8 bits, vous devez créer le en-têtes appropriés . En fin de compte, j'ai trouvé la solution bibliothèque de niveaux de gris permettant de créer des fichiers bitmap 8 bits (BMP). Le code est très simple:

Image image = Image.FromFile("c:/path/to/image.jpg");
GrayBMP_File.CreateGrayBitmapFile(image, "c:/path/to/8bpp/image.bmp");

Le code de ce projet est loin d'être joli, mais il fonctionne avec un petit problème simple à résoudre. L'auteur a codé en dur la résolution de l'image à 10x10. Les programmes de traitement d'image n'aiment pas cela. Le correctif est ouvert GrayBMP_File.cs (oui, nom de fichier génial, je sais) et remplacez les lignes 50 et 51 par le code ci-dessous. L'exemple définit la résolution sur 200x200, mais vous devez le changer pour le nombre approprié.

int resX = 200;
int resY = 200;
// horizontal resolution
Copy_to_Index(DIB_header, BitConverter.GetBytes(resX * 100), 24);
// vertical resolution 
Copy_to_Index(DIB_header, BitConverter.GetBytes(resY * 100), 28);
6
Brent Matzelle

Pour résumer quelques éléments ici: Il existe certaines options pixel par pixel qui, bien que simples, ne sont tout simplement pas rapides.

Le commentaire de @Luis a un lien vers: (archivé) https://web.archive.org/web/20110827032809/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color- image en niveaux de gris est superbe.

Il passe en revue trois options différentes et inclut des timings pour chacun.

6
jeffreypriebe

Le code ci-dessous est la solution la plus simple:

Bitmap bt = new Bitmap("imageFilePath");

for (int y = 0; y < bt.Height; y++)
{
    for (int x = 0; x < bt.Width; x++)
    {
        Color c = bt.GetPixel(x, y);

        int r = c.R;
        int g = c.G;
        int b = c.B;
        int avg = (r + g + b) / 3;
        bt.SetPixel(x, y, Color.FromArgb(avg,avg,avg));
    }   
}

bt.Save("d:\\out.bmp");
6
Prakash Ekhande