如何使用C#去灰度化一幅图像

时间:2023-02-10 20:20:59

灰度化一幅图像就是将图像的色彩信息全部丢掉,将24位的位图信息,用8位来表示,灰度图共有256级灰度等级,也就是将24位位图的一点如(255,255,255)转换成255,所以R,G,B三个值所乘的系数和为1
用伪语句可以表示如下

public bitmap GrayScal(bitmap orgbmp)
{
    建立一个与原图片等大的8位的图片
    取出原图像中的每一个点
    新图像的点=原图像点的红色量*系数1+绿色量*系数2+黄色量*系统3
    返回新图像
}

  ///   <summary>
    
///  对图像进行点运算,
    
///   </summary>
     public   class  PointTrans
    {
        
private   readonly   double  cb;
        
private   readonly   double  cg;
        
private   readonly   double  cr;

        
///   <summary>
        
///  做点运算,要给每一个偏量,做一下设置,比如做图像的灰度图就需要现设置
        
///   </summary>
        
///   <param name="cr"></param>
        
///   <param name="cg"></param>
        
///   <param name="cb"></param>
         public  PointTrans( double  cr,  double  cg,  double  cb)
        {
            
this .cr  =  cr;
            
this .cg  =  cg;
            
this .cb  =  cb;
        }

        
public   Bitmap GrayScaleBmp(Bitmap orgData)
        {
            
int  bmpWidth  =  orgData.Width, bmpHeight  =  orgData.Height;
            Bitmap destData 
=  ImageTools.CreateGrayscaleImage(bmpWidth, bmpHeight);
            Rectangle bmpRect
= new  Rectangle( 0 , 0 ,bmpWidth,bmpHeight);

            BitmapData orgBmpData 
=  orgData.LockBits(bmpRect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            BitmapData destBmpData 
=  destData.LockBits(bmpRect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
            ProcessFilter(orgBmpData,destBmpData);

            orgData.UnlockBits(orgBmpData);
            destData.UnlockBits(destBmpData);
            
return  destData;

        }


        
protected   unsafe   void  ProcessFilter(BitmapData sourceData, BitmapData destinationData)
        {
            
//  get width and height
             int  width  =  sourceData.Width;
            
int  height  =  sourceData.Height;

            
int  srcOffset  =  sourceData.Stride  -  width * 3 ;
            
int  dstOffset  =  destinationData.Stride  -  width;

            
//  do the job
             byte *  src  =  ( byte * ) sourceData.Scan0.ToPointer();
            
byte *  dst  =  ( byte * ) destinationData.Scan0.ToPointer();

            
//  for each line
             for  ( int  y  =   0 ; y  <  height; y ++ )
            {
                
//  for each pixel
                 for  ( int  x  =   0 ; x  <  width; x ++ , src  +=   3 , dst ++ )
                {
                    
* dst  =  ( byte ) (cr * src[RGB.R]  +  cg * src[RGB.G]  +  cb * src[RGB.B]);
                }
                src 
+=  srcOffset;
                dst 
+=  dstOffset;
            }
        }


    }