⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.cpp

📁 这是书上的代码
💻 CPP
字号:
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Cloud.h"
#include "Dib.h"

#include "math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define PI  3.14159265358979
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDib::CDib()
{
	m_Height=0;
	m_Width=0;

	hDIB=NULL;
	bmInfoHeader=NULL;
	bmpInfo =NULL;
	lpDIBBits=NULL;


}

CDib::~CDib()
{
	ClearMemory();
}
/////////////////////////////////////////////////////////////////////////
//打开并读取图像文件
void CDib::ReadDIBFile(LPTSTR lpFilename)
{

	BITMAPFILEHEADER bmfHeader;//图像文件头	
	CFile File;
	CFileException Err;
	if(!File.Open(lpFilename,CFile::modeRead|CFile::shareDenyNone,&Err))
	{
		AfxMessageBox(Err.m_cause);
		return;
	}
	
	
	File.Read(&bmfHeader,sizeof(bmfHeader));
	if(bmfHeader.bfType!=0x4d42)
	{
		AfxMessageBox("此文件不是位图文件");
		return;
	}
	
	
	DWORD Filelen=File.GetLength();
	if(bmfHeader.bfSize!=Filelen)
	{
		AfxMessageBox("该文件已经损坏!");
		return;
	}
	hDIB=NULL;
	hDIB=new BYTE[Filelen-sizeof(BITMAPFILEHEADER)];
	if(!hDIB)
	{
		AfxMessageBox("内存不够!");
		return;

	}
	File.Read(hDIB,Filelen-sizeof(BITMAPFILEHEADER));
	File.Close();

}

/////////////////////////////////////////////////////////////////////////
//装载DIB
void CDib::LoadDIB(LPTSTR lpFilename)
{
	ReadDIBFile(lpFilename);
	
	bmInfoHeader=(LPBITMAPINFOHEADER)hDIB;	
	bmpInfo=(LPBITMAPINFO)hDIB;
	
	int ColorsNum=GetDIBColorsNum(bmInfoHeader);
	lpDIBBits=(BYTE*)hDIB+ColorsNum*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER);
	
	m_Height=bmInfoHeader->biHeight;
	m_Width=bmInfoHeader->biWidth;


}

long CDib::GetImageHeight()
{
	return m_Height;
}

long CDib::GetImageWidth()
{
	return m_Width;
}

/////////////////////////////////////////////////////////////////////////
//从得到图像颜色数
int CDib::GetDIBColorsNum(BITMAPINFOHEADER* bmInfoHeader)
{
	int ColorsNum;//图像颜色数

	switch(bmInfoHeader->biBitCount)
	{
	case 1:
		ColorsNum=2;
		break;
	case 4:
		ColorsNum=16;
		break;
	case 8:
		ColorsNum=256;
		break;
	default:
		ColorsNum=0;
		break;		
	}

	return ColorsNum;
}
/////////////////////////////////////////////////////////////////////////
//把DIB选入到指定设备hDC
BOOL CDib::PaintDIB(HDC hDC,long width,long height)
{

	int bSuccess;
	HPALETTE hPal=NULL;
	HPALETTE hOldPal;
	if(!hDIB)
		return FALSE;

	if(!hPal)
		CreateDIBPalette();

	if(hPal)
	{
		hOldPal=SelectPalette(hDC,hPal,TRUE);
		RealizePalette(hDC);
	}

	SetStretchBltMode(hDC,COLORONCOLOR);
	
	bSuccess=StretchDIBits(hDC,0,0,width,
		                   height,0,0,m_Width,m_Height,lpDIBBits, 
	                       bmpInfo,DIB_RGB_COLORS,SRCCOPY);


	if(hOldPal)
		SelectPalette(hDC,hOldPal,FALSE);
	return bSuccess;
}

/////////////////////////////////////////////////////////////////////////
//生成自己的调色板
HPALETTE CDib::CreateDIBPalette()
{
	LOGPALETTE* lpPal;
	HPALETTE hPal=NULL;
	int wNumColors=GetDIBColorsNum(bmInfoHeader);

	lpPal=(LOGPALETTE*)new BYTE[wNumColors*sizeof(PALETTEENTRY)+2*sizeof(WORD)];
	lpPal->palNumEntries=wNumColors;
	lpPal->palVersion=1;
	for(int i=0;i<wNumColors;i++)
	{
    	lpPal->palPalEntry[i].peBlue=bmpInfo->bmiColors[i].rgbBlue;
    	lpPal->palPalEntry[i].peGreen=bmpInfo->bmiColors[i].rgbGreen;
    	lpPal->palPalEntry[i].peRed=bmpInfo->bmiColors[i].rgbRed;
    	lpPal->palPalEntry[i].peFlags=bmpInfo->bmiColors[i].rgbReserved=(BYTE)0;
	}
	hPal=CreatePalette(lpPal);
	return hPal;
}

/////////////////////////////////////////////////////////////////////////
//释放内存
void CDib::ClearMemory()
{
	delete[] hDIB;
	delete[] bmInfoHeader;
	delete[] bmpInfo;	
	delete[] lpDIBBits;


}
/////////////////////////////////////////////////////////////////////////
//获得DIB数据指针

HANDLE CDib::GetDIBHandle()
{
	return hDIB;
}

/////////////////////////////////////////////////////////////////////////
//从DIB获得DDB




//////////////////////////////////////////
//////////图像灰度线性变换函数
BOOL CDib::OnChangeBrightness(float fa,float fb)
{
	if(!lpDIBBits)
	{
		AfxMessageBox("请先打开图像");
		return FALSE;
	}
		
	BYTE* temDIBits;
	if(bmInfoHeader->biBitCount!=24)
	{
		AfxMessageBox("只能对24位真彩色的图像进行变换");
		return FALSE;
	}
	int w=m_Width;
	int h=m_Height;
	int sign=w%2;
	long total=w*h*3;
	long k=0;
	if(sign)
		w+=1;
	temDIBits=new BYTE[total];
	memcpy(temDIBits,lpDIBBits,total);
	for(int i=0;i<h;i++)
	{
		for(int j=0;j<w;j++)
		{
			float fTem;

			fTem=fa*temDIBits[k]+fb;//红色通道
			if(fTem>255)
			{
				lpDIBBits[k]=(BYTE)255;
			}else
			if(fTem<0)
			{
				lpDIBBits[k]=(BYTE)0;
			}else
			{
				lpDIBBits[k]=(BYTE)(fTem+0.5);
			}


			fTem=fa*temDIBits[k+1]+fb;//绿色通道
			if(fTem>255)
			{
				lpDIBBits[k+1]=(BYTE)255;
			}else
			if(fTem<0)
			{
				lpDIBBits[k+1]=(BYTE)0;
			}else
			{
				lpDIBBits[k+1]=(BYTE)(fTem+0.5);
			}


			fTem=fa*temDIBits[k+2]+fb;//蓝色通道
			if(fTem>255)
			{
				lpDIBBits[k+2]=(BYTE)255;
			}else
			if(fTem<0)
			{
				lpDIBBits[k+2]=(BYTE)0;
			}else
			{
				lpDIBBits[k+2]=(BYTE)(fTem+0.5);
			}


			if(k>=total)
				break;
			k+=3;
		}
	}


	return TRUE;
}


/////////////////////////////////////////////////////////////////
//////////////////灰度拉伸函数
BOOL CDib::OnGrayStretch(BYTE x1,BYTE x2,BYTE y1,BYTE y2)
{
	if(!lpDIBBits)
	{
		AfxMessageBox("请先打开图像");
		return FALSE;
	}
		
	if(bmInfoHeader->biBitCount!=24)
	{
		AfxMessageBox("只能对24位真彩色的图像进行变换");
		return FALSE;
	}

	int w=m_Width;
	int h=m_Height;
	int sign=w%2;
	long total=w*h*3;
	long k=0;
	if(sign)
		w+=1;

	BYTE A=(y2-y1)/(x2-x1);
	for(int i=0;i<h;i++)
	{
		for(int j=0;j<w;j++)
		{
			float fTem;
			if(lpDIBBits[k]>=x1&&lpDIBBits[k]<=x2)
			{
				fTem=lpDIBBits[k];
				lpDIBBits[k]=(BYTE)fTem*A+y1;
				lpDIBBits[k+1]=(BYTE)fTem*A+y1;
				lpDIBBits[k+2]=(BYTE)fTem*A+y1;
			}else if(lpDIBBits[k]<x1)
			{
				lpDIBBits[k]=y1;
				lpDIBBits[k+1]=y1;
				lpDIBBits[k+2]=y1;
			}else
			{
				lpDIBBits[k]=y2;
				lpDIBBits[k+1]=y2;
				lpDIBBits[k+2]=y2;

			}
			if(k>=total)
				break;
			k+=3;

		}
	}


	return TRUE;
}
/////////////////////////////////////////////////////////////////
//////////////////灰度化图像函数
BOOL CDib::OnChangeToGray()
{
	if(!lpDIBBits)
	{
		AfxMessageBox("请先打开图像");
		return FALSE;
	}
		
	if(bmInfoHeader->biBitCount!=24)
	{
		AfxMessageBox("只能对24位真彩色的图像进行变换");
		return FALSE;
	}
	int w=m_Width;
	int h=m_Height;
	int sign=w%2;
	long total=w*h*3;
	long k=0;
	if(sign)
		w+=1;

	for(int i=0;i<h;i++)
	{
		for(int j=0;j<w;j++)
		{
			float fTem;
			fTem=(float)(lpDIBBits[k]+lpDIBBits[k+1]+lpDIBBits[k+2])/3;//灰度值为三色RGB的平均值
			lpDIBBits[k]=(BYTE)fTem;
			lpDIBBits[k+1]=(BYTE)fTem;
			lpDIBBits[k+2]=(BYTE)fTem;		
			
			if(k>=total)
				break;
			k+=3;
		}
	}


	return TRUE;
}
////////////////////////////////////////////////////////
//直方图均衡化函数
void CDib::OnHistogramEqualize()
{
	if(!lpDIBBits)
	{
		AfxMessageBox("请先打开图像");
		return;
	}
		if(bmInfoHeader->biBitCount!=24)
	{
		AfxMessageBox("只能对24位真彩色的图像进行变换");
		return;
	}

		
	OnChangeToGray();//灰度化图像

	int w=m_Width;
	int h=m_Height;
	int sign=w%2;
	long total=w*h*3;
	long k=0;//像素lpBITBits的下标
	
	long Temp;
	BYTE bMap[256];//新的灰度表
	long iCount[256];//图像0-255每种灰度的点数
	for(int i=0;i<256;i++)
	{
		iCount[i]=0;
	}

	if(sign)
		w+=1;

	for(i=0;i<h;i++)//统计每一级灰度的点的数量
	{
		for(int j=0;j<w;j++)
		{
			iCount[lpDIBBits[k]]++;
			
			if(k>=total)
				break;
			k+=3;
		}
	}

	for(i=0;i<256;i++)//计算新的灰度表
	{
		Temp=0;
		for(int j=0;j<i;j++)
		{
			Temp+=iCount[j];
			
		}
		bMap[i]=(BYTE)(Temp*255/h/w);
	}


	k=0;
	for(i=0;i<h;i++)//给每个像素点付新值
	{
		for(int j=0;j<w;j++)
		{
			BYTE tem=lpDIBBits[k];
			lpDIBBits[k]=bMap[tem];
			lpDIBBits[k+1]=bMap[tem];
			lpDIBBits[k+2]=bMap[tem];
			
			if(k>=total)
				break;
			k+=3;
		}
	}

}
////////////////////////////////////////////////////////////////////////
///傅里叶变换In输入,其长度是图像占有字节数的两倍,i=偶数为实部,
//i=奇数为虚部;nn是一个数组代表图像的宽度和高度,
//sign为1或-1,分别表示正、负傅里叶变换 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -