原创
(原创)图像处理学习系列1:bmp文件的操作之色彩转换
2009-3-5 14:09
3385
8
8
分类:
软件与OS
接着上面的,可以做24位图片到8位的转换,仅支持bmp文件
这方面的网站;/
帖子
http://topic.csdn.net/t/20040824/09/3303224.html
基础知识
http://www.roboticfan.com/blog/user_2005/11932/archives/2008/2008111143115.shtml
程序
http://www.cppblog.com/windcsn/archive/2006/07/27/Grayscale.html
后面这个说的不错
写的时候遇到的问题?
1.使用BITMAPINFO的方法错误,搞昏了BITMAPINFO的结构和BMP文件的存储格式。
在文件的save的时候可以
m_file.Write(&pbmphdr,sizeof(BITMAPFILEHEADER));
m_file.Write(pbmpinfo,sizeof(BITMAPINFOHEADER));
m_file.Write(ColorRGB,ColorNum * sizeof(RGBQUAD));
在对bitmapinfo操作的时候,对颜色表不是简单的copy就可以的是,是在
BITMAPINFO里面的IMCOLOR结构中进行初始化的
2.指针的操作
BOOL Rgb2Gray(BITMAPFILEHEADER *pbmpfh , BITMAPINFO *pbmpinfo , BYTE *pbmpdata)
如果你在内部开辟空间的话,是返回不了地址的(郁闷的是,自己竟然不知道原因)
3.其实,BITMAPINFOHEADER和后面的 颜色表以及数据是在一个内存块中的,完全可以通过只传递BITMAPINFO指针
通过地址来查找颜色表和其他数据 要修改的太多了,暂且不动库函数了
/****************************************************************************
//彩色图片转换到灰度图片
**************************************************************/
BOOL Rgb2Gray(BITMAPFILEHEADER **pbmpfh , BITMAPINFO **pbmpinfo , BYTE **pbmpdata)
{
if ((*pbmpinfo)->bmiHeader.biBitCount < 24)
{
AfxMessageBox("请输入彩色图片!");
return FALSE;
}
LONG imagewidth = (*pbmpinfo)->bmiHeader.biWidth;
LONG imageheigth = (*pbmpinfo)->bmiHeader.biHeight;
LONG Linebyte=(imagewidth * (*pbmpinfo)->bmiHeader.biBitCount + 31)/32 * 4;
LONG ImageSize = imageheigth * Linebyte ;
LONG GrayImage_Linebyte=(imagewidth * 8 +31)/32 * 4;
LONG GrayImage_size=GrayImage_Linebyte* imageheigth;
BYTE *tempdata;
tempdata = (BYTE*)malloc(GrayImage_size);
memset(tempdata,0,GrayImage_size);
int width,heigth;
BYTE *psrc ;
BYTE *pdest;
int r,g,b;
psrc=*pbmpdata;
pdest=tempdata;
for (heigth = 0 ; heigth < imageheigth ;heigth++ )
{
for ( width = 0 ; width < imagewidth ; width++)
{
//psrc = pbmpdata+(ImageSize-Linebyte-
// heigth*Linebyte) + width*3;
//pdest = tempdata + (GrayImage_size - GrayImage_Linebyte - heigth * GrayImage_Linebyte ) +width;
b = *(psrc++);
g = *(psrc++);
r = *(psrc++);
*(pdest++)=(BYTE)(r*0.299 + g*0.587 + b*0.114);
}
}
BITMAPFILEHEADER *fher;
fher = new BITMAPFILEHEADER;
fher->bfType = 0x4D42;
fher->bfReserved1=0;
fher->bfReserved2=0;
fher->bfSize = GrayImage_size;
fher->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) ;
memcpy(*pbmpfh,fher, sizeof(BITMAPFILEHEADER));
delete fher;
BITMAPINFO *info;
info = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));;
info->bmiHeader.biBitCount=8;
info->bmiHeader.biClrUsed=0;
info->bmiHeader.biCompression=BI_RGB;
info->bmiHeader.biHeight=imageheigth;
info->bmiHeader.biPlanes =1 ;
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info->bmiHeader.biSizeImage = 0;
info->bmiHeader.biWidth=imagewidth;
info->bmiHeader.biXPelsPerMeter=0;
info->bmiHeader.biYPelsPerMeter=0;
for ( int i=0 ;i < 256 ;i++)
{
info->bmiColors.rgbBlue = (BYTE)i;
info->bmiColors.rgbGreen = (BYTE)i;
info->bmiColors.rgbRed = (BYTE)i;
info->bmiColors.rgbReserved= (BYTE)i;
}
free((*pbmpinfo));
(*pbmpinfo) = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
memcpy((*pbmpinfo),info, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
free( *pbmpdata);
*pbmpdata =(BYTE*)((*pbmpinfo)+sizeof(BITMAPINFOHEADER)+256 * sizeof(RGBQUAD));
*pbmpdata = (BYTE*)malloc(GrayImage_size);
memcpy(*pbmpdata,tempdata,GrayImage_size);
free(tempdata);
delete info;
return TRUE;
}
文章评论(0条评论)
登录后参与讨论