How to convert pixel formats? From 32bppRGB to 16bpp grayscale in C#

后端 未结 2 1589
情深已故
情深已故 2021-01-18 18:17

I need to do some thresholding for my image. The threshold filter function just accepts 8-16bpp grayscale. My bitmap picture has the 32bppRGB

相关标签:
2条回答
  • 2021-01-18 18:37

    Use AForge.NET framework Grayscale filter

    The filter accepts 24, 32, 48 and 64 bpp color images and produces 8 (if source is 24 or 32 bpp image) or 16 (if source is 48 or 64 bpp image) bpp grayscale image.

    Then apply threshold filter.

    0 讨论(0)
  • 2021-01-18 18:41

    Easiest way:

    public static Bitmap MakeGrayscale(Bitmap original)
     {
        //make an empty bitmap the same size as original
        Bitmap newBitmap = new Bitmap(original.Width, original.Height);
    
       for (int i = 0; i < original.Width; i++)
        {
           for (int j = 0; j < original.Height; j++)
           {
              //get the pixel from the original image
              Color originalColor = original.GetPixel(i, j);
    
             //create the grayscale version of the pixel
              int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59)
                  + (originalColor.B * .11));
    
             //create the color object
              Color newColor =  Color.FromArgb(grayScale, grayScale, grayScale);
    
              //set the new image's pixel to the grayscale version
              newBitmap.SetPixel(i, j, newColor);
             }
         }
    
        return newBitmap;
     }
    

    Faster way:

    public static Bitmap MakeGrayscale2(Bitmap original)
     {
        unsafe
        {
           //create an empty bitmap the same size as original
           Bitmap newBitmap = new Bitmap(original.Width, original.Height);
    
          //lock the original bitmap in memory
           BitmapData originalData = original.LockBits(
              new Rectangle(0, 0, original.Width, original.Height),
              ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    
          //lock the new bitmap in memory
           BitmapData newData = newBitmap.LockBits(
              new Rectangle(0, 0, original.Width, original.Height), 
             ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
    
           //set the number of bytes per pixel
           int pixelSize = 3;
    
          for (int y = 0; y < original.Height; y++)
           {
              //get the data from the original image
              byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
    
             //get the data from the new image
              byte* nRow = (byte*)newData.Scan0 + (y * newData.Stride);
    
             for (int x = 0; x < original.Width; x++)
              {
                 //create the grayscale version
                 byte grayScale = 
                   (byte)((oRow[x * pixelSize] * .11) + //B
                    (oRow[x * pixelSize + 1] * .59) +  //G
                    (oRow[x * pixelSize + 2] * .3)); //R
    
                //set the new image's pixel to the grayscale version
                 nRow[x * pixelSize] = grayScale; //B
                 nRow[x * pixelSize + 1] = grayScale; //G
                 nRow[x * pixelSize + 2] = grayScale; //R
              }
           }
    
          //unlock the bitmaps
           newBitmap.UnlockBits(newData);
           original.UnlockBits(originalData);
    
          return newBitmap;
        }
     }
    

    Fastest way:

    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;
     }
    
    0 讨论(0)
提交回复
热议问题