/* 头文件 */
#include <afx.h>
#include <windows.h>
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
/*复数定义*/
/* 全局变量 */
int nWidth; //图像的宽度
int nHeight; //图像的高度
int nColorBits; //每个像素所占的位数
int nColor; //图像的颜色数
int nLen; //图像文件的大小,以字节数计
int nByteWidth; //图像每行的字节数
BYTE *lpBitmap; //指向图像首字节的指针
BYTE *lpBits; //指向图像实际数据的指针
/* 函数声明 */
void OpenFile(CString FileName);
void SaveFile(CString FileName);
void HistogramStat(long bCount[], long gCount[], long rCount[]);
void HistogramEq();
/************************************************************************
* 函数名称: - OpenFile();
* 参数: - CString FileName :图像的路径和文件名
* 返回值: - 无
* 功能: - 读取一幅BMP图像
************************************************************************/
void OpenFile(CString FileName)
{
//创建文件句柄
HANDLE hFile =::CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == 0)
{
printf("不能打开文件,请重新选择!\n");
return ;
}
//读取图像文件
DWORD WriteNum;
BITMAPFILEHEADER BFH; //文件头
ReadFile(hFile,&BFH,14,&WriteNum,NULL);//读取文件头,共14个字节
if((BFH.bfType != 'MB')||(WriteNum != sizeof(BITMAPFILEHEADER)))
{
printf("不是BMP位图文件或数据有误!\n");
return ;
}
nLen = GetFileSize(hFile,NULL)-sizeof(BITMAPFILEHEADER); //获取文件的长度
lpBitmap= new BYTE[nLen];//存放图像,包括图像的信息头、调色板和像素数据
ReadFile(hFile,lpBitmap,nLen,&WriteNum,NULL); //读取图像数据
//设置全局变量的值
BITMAPINFOHEADER *BIH = ((BITMAPINFOHEADER *)lpBitmap);
//图像文件的信息头
nWidth = BIH->biWidth; //图像的宽度
nHeight = BIH->biHeight; //图像的高度
nColorBits = BIH->biBitCount; //图像的颜色数
nByteWidth = (nWidth*nColorBits+31)/32*4; //图像的扫描宽度
nColor = (nColorBits>8) ? 0 : (1<<nColorBits); //调色板中的颜色数
lpBits = lpBitmap + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*nColor; //指向图像数据的实际位置
CloseHandle(hFile); //关闭文件句柄
}
/*************************************************************************
* 函数名称: - SaveFile();
* 参数: - CString FileName - 图像的路径和文件名
* 返回值: - 无
* 功能: - 保存一幅BMP图像
************************************************************************/
void SaveFile(CString FileName)
{
//创建一个文件来保存图像文件
HANDLE hFile = ::CreateFile(FileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == 0)
{
printf("不能创建文件,请重新选择!\n");
return;
}
//创建一个文件头,并保存到创建的文件中
unsigned long WriteNum;
BITMAPFILEHEADER BFH;
BFH.bfType = 'MB';
BFH.bfSize = nLen + sizeof(BITMAPFILEHEADER);
BFH.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nColor * sizeof(RGBQUAD);
BFH.bfReserved1 = BFH.bfReserved2 = 0;
WriteFile(hFile,&BFH,sizeof(BITMAPFILEHEADER),&WriteNum,NULL);
//保存改变的位图文件数据
WriteFile(hFile,(BITMAPINFOHEADER *)lpBitmap,nLen,&WriteNum,NULL);
CloseHandle(hFile); //关闭文件句柄
}
/*************************************************************************
* 函数名称: - HistogramStat();
* 参数: - long bCount[];
* - long gCount[];
* - long rCount[];
* 返回值: - 无
* 功能: - 统计图像各级灰度的像素的个数,
* 当是256色图像,返回值放在bCount[]中
* 真彩色图像蓝色、绿色、红色分量依次放在三个参数变量中
**************************************************************************/
void HistogramStat(long bCount[], long gCount[], long rCount[])
{
// 赋初值
for (int i = 0; i < 256; i++)
{
rCount[i] = 0;
gCount[i] = 0;
bCount[i] = 0;
}
//统计各个灰度级像素的个数
for (i=0;i<nHeight;i++)
{
for (int j=0;j<nWidth;j++)
{
if(nColorBits == 8)
{
unsigned char *pData = lpBits + i * nByteWidth + j;
bCount[*pData]++;
}
else if(nColorBits == 24)
{
unsigned char *pData = lpBits + i * nByteWidth + j*3;
bCount[*pData]++;
gCount[*(pData+1)]++;
rCount[*(pData+2)]++;
}
}
}
}
/*************************************************************************
* 函数名称: - HistogramEq();
* 参数: - 无
* 返回值: - 无
* 功能: - 直方图均衡
************************************************************************/
void HistogramEq()
{
//各个颜色分量的亮度映射表
BYTE grayMap[256],rMap[256],gMap[256],bMap[256];
//各个颜色分量亮度统计表
long rCount[256],gCount[256],bCount[256];
long i,j;
//直方图统计,统计各个灰度的像素,256色图像的结果放在bCount中
HistogramStat(bCount,gCount,rCount);
//计算每个灰度级对应的新的像素值
double TotalNum = nWidth * nHeight;
for (i = 0; i < 256; i++)
{
if(nColorBits == 8)
{
long grayTemp = 0;
for (j=0;j<=i;j++) grayTemp += bCount[j];
grayMap[i] = (BYTE) (grayTemp * 255/TotalNum);//对应的新灰度值
}
else if(nColorBits == 24)
{
long rTemp = 0, gTemp = 0, bTemp = 0;
for (j = 0; j <= i ; j++)
{
rTemp += rCount[j];
gTemp += gCount[j];
bTemp += bCount[j];
}
//计算对应的新灰度值
rMap[i] = (BYTE) (rTemp * 255/TotalNum);
gMap[i] = (BYTE) (gTemp * 255/TotalNum);
bMap[i] = (BYTE) (bTemp * 255/TotalNum);
}
}
//对像素的灰度赋新值
for (i = 0; i < nHeight; i++)
{
for(j = 0; j < nWidth; j++)
{
if(nColorBits == 8)
{
unsigned char *pData = lpBits + i*nByteWidth+j;
*pData = grayMap[*pData];
}
else if(nColorBits == 24)
{
unsigned char *pData = lpBits + i*nByteWidth + j*3;
*pData = bMap[*pData];
*(p