请问 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种颜色中,则用代替色的索引值填入位图数据中。
请问该如何实现啊
读取文件时候 是用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; }
------解决方案--------------------