请问 mfc 读取位图 RGB分量,并且改变RGB分量值多谢!

请教 mfc 读取位图 RGB分量,并且改变RGB分量值谢谢!!
请问该如何实现啊
读取文件时候 是用CFile类来 读取位图信息吗?
我用 CFile类这样读
  CFile openBmp;
openBmp.Open("demo.bmp", CFile::modeReadWrite);

openBmp.Read(m_bitmapFileHeader, sizeof(BITMAPFILEHEADER));//读取位图文件头信息 14个字节
openBmp.Read(m_pBitmapInfoHeader, sizeof(BITMAPINFOHEADER));//读取位图信息头 40个字节
openBmp.Read(m_pRGB, sizeof(RGBQUAD)); //我这里 读取颜色表做法 对吗、、
  openBmp.Close();
请问该怎样正确读取 并且改变 RGB分量啊 比如我想把 一个 256色的位图 或者 24位真彩位图 读进来 然后 改变RGB分量
使其变成 灰度图 应该怎么做啊??

------解决方案--------------------
用宏啊
COLORREF clr = RGB(255, 108, 250);
BYTE red = GetRValue(clr);
BYTE green = GetGValue(clr);
BYTE blue = GetBValue(clr);

转灰度图,网上很多的啊,http://download.****.net/source/1360771
------解决方案--------------------
下面介绍的算法能够比较好地实现真彩图到256色图的转换。它的思想是:准备一个长度为4096的数组,代表4096种颜色。对图中的每一个象素,取R、G、B的最高四位,拼成一个12位的整数,对应的数组元素加1。全部统计完后,就得到了这4096种颜色的使用频率。其中,可能有一些颜色一次也没用到,即对应的数组元素为零(假设不为零的数组元素共有PalCounts个)。将这些为零的数组元素清除出去,使得前PalCounts个元素都不为零。将这PalCounts个数按从大到小的顺序排列(这里我们使用起泡排序)。这样,前256种颜色就是用的最多的颜色,它们将作为调色板上的256种颜色。对于剩下的PalCounts-256种颜色并不是简单地丢弃,而是用前256种颜色中的一种来代替,代替的原则是找有最小平方误差的那个。再次对图中的每一个象素,取R、G、B的最高四位,拼成一个12位的整数,如果对应值在前256种颜色中,则直接将该索引值填入位图数据中,如果是在后PalCounts-256种颜色中,则用代替色的索引值填入位图数据中。
C/C++ code
//(14)各色位图转换成8位灰度图$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   
  void   defLianBiao::TurnToGrey(LPSTR lpDib)   
  {   
    
  LPSTR       lpNewDIBBits;//   指向DIB灰度图图像开始处象素的指针   
  unsigned   char   *   ired;   
  unsigned   char   *   igreen;   
  unsigned   char   * iblack;   
  long   i,j;//   循环变量   
  unsigned   char   *   lpdest;   
  //lpdest=(unsigned   char   *)::malloc(lHeight*lWidth);   
  lpdest=   new   unsigned   char   [lHeight*lWidth];   
  int   n=0;   
  int   PictureBits;   
  PictureBits=DIBBits(lpDib)/8;   
  if   (PictureBits==0)//||PictureBits<=1)//不处理非整数字节的图像格式   
  {   
  AfxMessageBox("不支持该图像的数据格式");   
  return;   
  }   
  RGBQUAD   *lpRGBquad;   
  lpRGBquad=(RGBQUAD   *)&lpDib[sizeof(BITMAPINFOHEADER)];//位图信息头后面为调色板   
  unsigned   char* lpSrc;   
  n=0;   
  if(PictureBits==1)//256色彩色位图   
  for(j=0;j<lHeight;j++)   
  for(i=0;i<lWidth;i++)   
  {   
  lpSrc   =   (unsigned   char*)lpDIBBits   +   lLineBytes   *   j   +   i;   
  ired=   &lpRGBquad[*lpSrc].rgbRed;   
  igreen   =&   lpRGBquad[*lpSrc].rgbGreen;   
  iblack   =   &lpRGBquad[*lpSrc].rgbBlue;   
  lpdest[n]   =(unsigned   char)(0.299*(*ired)+0.587*(*igreen)+0.114*(*iblack));   
  n++;   
  }   
  else//24/32位彩色位图   
  {   
    
  lLineBytes=WIDTHBYTES(lWidth   *   8*PictureBits);   
  for   (j=0;j<lHeight;j++)   
  for(i=0,n=0;i<PictureBits*lWidth;i+=PictureBits,n++)   
  {   
    
  ired=   (unsigned   char*)lpDIBBits   +   lLineBytes   *j+i+2;   
  igreen   =   (unsigned   char*)lpDIBBits+lLineBytes   *j+i+1;   
  iblack   =   (unsigned   char*)lpDIBBits   +lLineBytes   *j+i;   
  lpdest[j*lWidth+n]   =(unsigned   char)(0.299*(*ired)+0.587*(*igreen)+0.114*(*iblack));   
    
  }   
  }   
  LPBITMAPINFOHEADER   lpBI;//位图信息头   
  //   读取BITMAPINFO结构,初始化指针   
  lpBI   =   (LPBITMAPINFOHEADER)lpDib;//[sizeof(BITMAPFILEHEADER)];   
  lpBI->biBitCount=8;   
  //设置256色灰度调色板   
  for   (i   =   0;   i   <   256;   i++)   
  {   
  lpRGBquad[i].rgbRed   =(unsigned   char)i;//   读取红色分量   
  lpRGBquad[i].rgbGreen   =(unsigned   char)i;//   读取绿色分量   
  lpRGBquad[i].rgbBlue   =   (unsigned   char)i;//   读取红色分量   
  lpRGBquad[i].rgbReserved   =   0;//   保留位   
  }   
  lpNewDIBBits=   ::FindDIBBits(lpDib);//   找到DIB图像象素起始位置   
  lLineBytes=WIDTHBYTES(lWidth   *   8);   
  for(j=0;j<lHeight;j++)   
  for(i=0;i<lWidth;i++)   
  {   
    
    
  lpSrc=(unsigned   char*)lpNewDIBBits+lLineBytes*j+i;   
  *lpSrc=lpdest[j*lWidth+i];   
  }   
  //::free((void   *)lpdest);   
  delete   lpdest;   
  }

------解决方案--------------------