24位位图转成8位灰度位图
2010-04-21 11:28
309 查看
24位转8位灰度比较简单,先设置调色板,如下样子
(0,0,0,0)(1,1,1,0)(2,2,2,0)……一共256个,用公式gray = (0.114*Blue+0.587*Green+0.299*Red)得到的gray为该像素点在8位位图中调色板的索引,所以,只要把24位中每个像素点中的数据按公式算出索引,再写入,就完成了,代码如下:
void CDib::ConverTo8BitGray()
{
//24位转换为8位灰度
LPBITMAPINFOHEADER lpbi;
if(!hdib)
return;
lpbi = (BITMAPINFOHEADER*)hdib;
int height = lpbi->biHeight;
//两个宽度
LONG lLineBytes24=((lpbi->biWidth*24+31)/32*4);
LONG lLineBytes8=((lpbi->biWidth*8+31)/32*4);
//源图像的指针,申请一块足够大的内存
BYTE* srcBits ;//= (BYTE*)malloc(lLineBytes24*height);
//使其指向源图像的图像数据起始地址
srcBits = (BYTE*)lpbi+sizeof(BITMAPINFOHEADER);
//转换后的图像数据指针(大小为图片大小和调色板大小之和
int iPaletteSize = sizeof(RGBQUAD)*256;//调色板大小
BYTE* dstBits = (BYTE*)malloc(iPaletteSize+lLineBytes8*height);
RGBQUAD* pRGB = (RGBQUAD *)dstBits;//调色板指针,指向数据部分开始地址
//写入调色板数据
for(int i=0; i<256; i++)
{
pRGB->rgbBlue = pRGB->rgbGreen = pRGB->rgbRed = i;
pRGB->rgbReserved = 0;
pRGB++;
}
for(int y=0; y<height; y++)
{
for(int x=0, n=0; x<lLineBytes24; x+=3)
{
BYTE B = *(srcBits+lLineBytes24*y+x);//蓝
BYTE G = *(srcBits+lLineBytes24*y+x+1);//绿
BYTE R = *(srcBits+lLineBytes24*y+x+2);//红
int gray = (int)(0.114*B+0.587*G+0.299*R);//灰度公式
*(dstBits + iPaletteSize + lLineBytes8*y + n) = gray;//写入灰度值
n++;
}
}
//8位BMP的信息头
BITMAPINFOHEADER bi;
bi.biBitCount=8;
bi.biClrImportant=0;
bi.biClrUsed=0;
bi.biCompression=0L;
bi.biHeight=Height();
bi.biPlanes=1;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biSizeImage=Height()*lLineBytes24;
bi.biWidth=Width();
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
SetBitmapinfoAndBits(bi, dstBits);
CString FileName;
strFileName.Delete(strFileName.GetLength()-4, 4);
FileName.Format("%s的8位灰度图.bmp",strFileName);
//调用保存文件函数
SaveFile(FileName);
//收尾清除指针内存
//free(srcBits);
srcBits = NULL;
free(dstBits);
dstBits = NULL;
AfxMessageBox("已经转换成8位灰度图,另存为:"+FileName);
}
关于读取保存设置等会在别的文章中写
(0,0,0,0)(1,1,1,0)(2,2,2,0)……一共256个,用公式gray = (0.114*Blue+0.587*Green+0.299*Red)得到的gray为该像素点在8位位图中调色板的索引,所以,只要把24位中每个像素点中的数据按公式算出索引,再写入,就完成了,代码如下:
void CDib::ConverTo8BitGray()
{
//24位转换为8位灰度
LPBITMAPINFOHEADER lpbi;
if(!hdib)
return;
lpbi = (BITMAPINFOHEADER*)hdib;
int height = lpbi->biHeight;
//两个宽度
LONG lLineBytes24=((lpbi->biWidth*24+31)/32*4);
LONG lLineBytes8=((lpbi->biWidth*8+31)/32*4);
//源图像的指针,申请一块足够大的内存
BYTE* srcBits ;//= (BYTE*)malloc(lLineBytes24*height);
//使其指向源图像的图像数据起始地址
srcBits = (BYTE*)lpbi+sizeof(BITMAPINFOHEADER);
//转换后的图像数据指针(大小为图片大小和调色板大小之和
int iPaletteSize = sizeof(RGBQUAD)*256;//调色板大小
BYTE* dstBits = (BYTE*)malloc(iPaletteSize+lLineBytes8*height);
RGBQUAD* pRGB = (RGBQUAD *)dstBits;//调色板指针,指向数据部分开始地址
//写入调色板数据
for(int i=0; i<256; i++)
{
pRGB->rgbBlue = pRGB->rgbGreen = pRGB->rgbRed = i;
pRGB->rgbReserved = 0;
pRGB++;
}
for(int y=0; y<height; y++)
{
for(int x=0, n=0; x<lLineBytes24; x+=3)
{
BYTE B = *(srcBits+lLineBytes24*y+x);//蓝
BYTE G = *(srcBits+lLineBytes24*y+x+1);//绿
BYTE R = *(srcBits+lLineBytes24*y+x+2);//红
int gray = (int)(0.114*B+0.587*G+0.299*R);//灰度公式
*(dstBits + iPaletteSize + lLineBytes8*y + n) = gray;//写入灰度值
n++;
}
}
//8位BMP的信息头
BITMAPINFOHEADER bi;
bi.biBitCount=8;
bi.biClrImportant=0;
bi.biClrUsed=0;
bi.biCompression=0L;
bi.biHeight=Height();
bi.biPlanes=1;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biSizeImage=Height()*lLineBytes24;
bi.biWidth=Width();
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
SetBitmapinfoAndBits(bi, dstBits);
CString FileName;
strFileName.Delete(strFileName.GetLength()-4, 4);
FileName.Format("%s的8位灰度图.bmp",strFileName);
//调用保存文件函数
SaveFile(FileName);
//收尾清除指针内存
//free(srcBits);
srcBits = NULL;
free(dstBits);
dstBits = NULL;
AfxMessageBox("已经转换成8位灰度图,另存为:"+FileName);
}
关于读取保存设置等会在别的文章中写
相关文章推荐
- bmp位图文件:读取、写入、24位真彩转8位灰度、灰度图的二值化
- 24位转8位位图,不是灰度,有颜色的,尽量减少失真
- 24位真色位图转化为8位灰度位图
- 24位真彩色位图转换成8位灰度图片的代码实现
- 24位真彩色位图和8位灰度位图相互转换(C语言实现)
- 24位真彩色位图转换成8位灰度图片的代码实现
- 24位位图转化为8位位图 位图头部信息BITMAPFILEHEADER BITMAPINFOHEADER修改代码
- 如何在Java应用程序中读取8位,24位Microsoft Windows位图(精品)
- C# 图像处理:将图像(24位真彩)转为 8位灰度图像 采用了内存法,大大提高了效率
- 实现1位,4位,8位,24位BMP位图的互相转换的方法,32位转24位
- 将24位位图转换8位位图
- Java实现24位真彩转换为8位灰度图片
- 24位真彩色图像转8位灰度图像
- 24位位图转灰度
- 24位位图转8位灰度图
- 将24位真彩色图转换为8位灰度图片
- BMP的8位位图转换24位位图
- 24位位图转8位灰度图
- C++8位和24位bmp位图平滑、锐化和二值处理,24位真彩图的灰度化
- c# 24位圖像轉8位灰度圖像(數組方式)