首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

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

2012-02-15 
请教 mfc 读取位图 RGB分量,并且改变RGB分量值谢谢!!请问该如何实现啊读取文件时候 是用CFile类来 读取位

请教 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.csdn.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;     }
------解决方案--------------------


不用CFile读,直接用LoadImage加载位图进一个内存DC,然后用GetDIBits或是GetBitmapBits读出位图进一个数组,用GetBitmap(&bmpx)获取位图信息,然后通过
rgb=y*bmpx.bmWidthBytes+x*(bmpx.bmBitsPixel/8)来获取每一个点在数组中的位置,x,y是点的坐标,rgb是B色,rgb+1是G色,rgb+2是R色.
[解决办法]
RGBQUAD bmiColors[1]; //这里为什么是 长度大小为1 的数组啊 我看程序都好像不是啊
==============
这个确实不是1,一般使用BITMAPINFO的时候,大多数情况是定义一个指针,然后根据色彩表大小new一片空间,然后再将BMP信息头读进去。或者将整个文件读入内存,然后将指针指到信息头起始地址。 它的大小是根据BITMAPINFOHEADER结构中的biBitCount来自动调整的.
[解决办法]

探讨
啊 这样子啊、、 MSDN 上的错误啊 让我看了 老半天、、、、

热点排行