www.pudn.com > DigtalImageProc.rar > memBitmap.cpp


 
#include "stdafx.h" 
#include "memory.h" 
#include "memBitmap.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
memBitmap::memBitmap() 
{ 
	flag=0; 
	Scale=1.0f; 
} 
 
BOOL memBitmap::CreateDirect(int ImageWidth,int ImageHeight) 
{ 
	Release(); 
	flag=0; 
	Scale=1.0f; 
	BytesPerLine=ImageWidth*3; 
	if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4; 
	lenth=long(ImageHeight)*BytesPerLine; 
	bData=new BYTE[lenth+54L]; 
	if(!bData) 
	{ 
		AfxMessageBox("内存分配失败"); 
		return FALSE; 
	} 
	FillMemory(bData,lenth+54L,255); 
	flag=1; 
	bFileHeader=(LPBITMAPFILEHEADER)bData; 
	bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER)); 
	bBMI=(LPBITMAPINFO)bInfoHeader; 
	bInfoHeader->biWidth=ImageWidth; 
	bInfoHeader->biHeight=ImageHeight; 
	int xx = sizeof(BITMAPINFOHEADER); 
	bInfoHeader->biSize=40; 
	WORD bmptemp=(WORD)'M'; 
	bmptemp<<=8; 
	bmptemp|=(BYTE)'B'; 
	bFileHeader->bfType=bmptemp; 
	bFileHeader->bfOffBits=54; 
	bFileHeader->bfReserved1=0; 
	bFileHeader->bfReserved2=0; 
	bInfoHeader->biPlanes=1; 
	bInfoHeader->biBitCount=24; 
	bInfoHeader->biCompression=0; 
	bInfoHeader->biXPelsPerMeter=0; 
	bInfoHeader->biYPelsPerMeter=0; 
	bInfoHeader->biClrUsed=0; 
	bInfoHeader->biClrImportant=0; 
	bitData=bData+54; 
	bInfoHeader->biSizeImage=lenth; 
	bFileHeader->bfSize=lenth+54; 
	return TRUE; 
} 
 
memBitmap::memBitmap(int cx,int cy,class memBitmap &bm) 
{ 
	flag=0; 
	Scale=1.0f; 
	BytesPerLine=cx*3; 
	if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4; 
	lenth=long(cy)*BytesPerLine; 
	bData=new BYTE[lenth+54L]; 
	if(!bData) 
	{ 
		AfxMessageBox("内存分配失败"); 
		return ; 
	} 
	flag=1; 
	CopyMemory(bData,bm.bData,54); 
	bFileHeader=(LPBITMAPFILEHEADER)bData; 
	bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER)); 
	bBMI=(LPBITMAPINFO)bInfoHeader; 
	bInfoHeader->biWidth=cx; 
	bInfoHeader->biHeight=cy; 
	bitData=bData+54; 
	bInfoHeader->biSizeImage=lenth; 
	bFileHeader->bfSize=lenth+54; 
	Scale=bm.GetScale(); 
} 
 
BOOL memBitmap::Load(LPCTSTR filename) 
{ 
	CString str(filename,256); 
	if(str.Find(".bmp")==-1) 
		return false; 
	CFile file; 
	CFileException e; 
	if(!file.Open(filename,CFile::modeRead,&e)) 
	{ 
		#ifdef _DEBUG   
			AfxMessageBox("文件打不开"); 
		#endif 
		return FALSE; 
	} 
	file.Seek(0L,CFile::begin); 
	unsigned long int FileLenth; 
	FileLenth=file.GetLength(); 
	lenth=FileLenth; 
	bData= (BYTE *)malloc(lenth*sizeof(BYTE)); 
	if(!bData) 
	{ 
		AfxMessageBox("内存分配失败"); 
		return FALSE; 
	} 
	if(!file.ReadHuge(bData,FileLenth)) 
	{ 
		AfxMessageBox("读数据错"); 
		return FALSE; 
	} 
	flag=1; 
	bFileHeader=(LPBITMAPFILEHEADER)bData; 
	bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER)); 
	bBMI=(LPBITMAPINFO)bInfoHeader; 
	bitData=bData+54; 
	if(((unsigned char)bFileHeader->bfType!='B')||\ 
		   ((unsigned char)(bFileHeader->bfType>>8)!='M') ) 
	{ 
		AfxMessageBox("不是合法的Bmp文件"); 
		return FALSE; 
	} 
	file.Close(); 
	if(bInfoHeader->biCompression!=0) 
	{ 
		AfxMessageBox("本系统仅支持未压缩图象"); 
		return FALSE; 
	} 
	BytesPerLine=bInfoHeader->biWidth*(bInfoHeader->biBitCount/8); 
	if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4; 
	if(bInfoHeader->biBitCount==24)	return TRUE; 
	else if(bInfoHeader->biBitCount==8) 
		{ 
			BYTE Palette[256][3]; 
			BYTE *ImageData=bData+bFileHeader->bfOffBits; 
			int i,j; 
			for(i=0;i<256;i++) 
			{ 
				for(j=0;j<3;j++) 
				{ 
					Palette[i][j]=*(bitData+i*4+j); 
				} 
			} 
			int width=bInfoHeader->biWidth; 
			int height=bInfoHeader->biHeight; 
			int OldBytes=BytesPerLine; 
			flag=0; 
			CreateDirect(width,height); 
			for(j=0;jbiBitCount==4) 
		{ 
			BYTE Palette[16][3]; 
			BYTE *ImageData=bData+bFileHeader->bfOffBits; 
			int i,j; 
			for(i=0;i<16;i++) 
			{ 
				for(j=0;j<3;j++) 
				{ 
					Palette[i][j]=*(bitData+i*4+j); 
				} 
			} 
			int width=bInfoHeader->biWidth; 
			int height=bInfoHeader->biHeight; 
			int OldBytes=(width+1)/2; 
			if(OldBytes%4!=0)OldBytes=(OldBytes/4+1)*4; 
			flag=0; 
			CreateDirect(width,height); 
			for(j=0;j>=4; 
						Index&=0xf; 
					} 
					BYTE b=Palette[Index][0]; 
					BYTE g=Palette[Index][1]; 
					BYTE r=Palette[Index][2]; 
					SetPixel(i,height-j-1,RGB(r,g,b)); 
				} 
			} 
			flag=1; 
			return TRUE; 
		} 
		else if(bInfoHeader->biBitCount==1) 
		{ 
			BYTE Palette[2][3]; 
			BYTE *ImageData=bData+bFileHeader->bfOffBits; 
			int i,j; 
			for(i=0;i<2;i++) 
			{ 
				for(j=0;j<3;j++) 
				{ 
					Palette[i][j]=*(bitData+i*4+j); 
				} 
			} 
			int width=bInfoHeader->biWidth; 
			int height=bInfoHeader->biHeight; 
			int OldBytes=(width+1)/8; 
			if(OldBytes%4!=0)OldBytes=(OldBytes/4+1)*4; 
			flag=0; 
			CreateDirect(width,height); 
			for(j=0;j>=(7-i%8); 
					Index&=1; 
					BYTE b=Palette[Index][0]; 
					BYTE g=Palette[Index][1]; 
					BYTE r=Palette[Index][2]; 
					SetPixel(i,height-j-1,RGB(r,g,b)); 
				} 
			} 
			flag=1; 
			return TRUE; 
		} 
		else 
		{ 
			AfxMessageBox("非法的颜色数"); 
			return FALSE; 
		} 
	 
} 
 
BOOL memBitmap::Save(LPCTSTR filename) 
{ 
	CString str(filename,256); 
	if(str.Find(".bmp")==-1) 
	{ 
		AfxMessageBox("本系统仅支持Bmp格式的输出"); 
		return FALSE; 
	} 
	CFile file; 
	CFileException e; 
	if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite,&e)) 
	{ 
		#ifdef _DEBUG   
			AfxMessageBox("文件打不开"); 
		#endif 
		return FALSE; 
	} 
	file.Seek(0L,CFile::begin); 
	if(flag==1) 
	{ 
		file.Write(bData,lenth+54); 
	} 
	file.Close(); 
	return TRUE; 
} 
 
void memBitmap::Display(int x,int y,CDC *dc) 
{ 
	dc->SetStretchBltMode(HALFTONE); 
	StretchDIBits(dc->GetSafeHdc(),\ 
				x,y,int(Scale*bInfoHeader->biWidth),int(Scale*bInfoHeader->biHeight),\ 
				0,0,bInfoHeader->biWidth,bInfoHeader->biHeight,\ 
				bitData,bBMI,DIB_RGB_COLORS,SRCCOPY); 
} 
 
void memBitmap::Display(int x,int y,int cx,int cy,CDC *dc) 
{ 
	dc->SetStretchBltMode(HALFTONE); 
	StretchDIBits(dc->GetSafeHdc(),\ 
				x,y,cx,cy,\ 
				0,0,bInfoHeader->biWidth,bInfoHeader->biHeight,\ 
				bitData,bBMI,DIB_RGB_COLORS,SRCCOPY); 
} 
 
memBitmap::~memBitmap() 
{ 
	if((flag==1)&&(bData)) 
		delete bData; 
	flag=0; 
} 
 
int memBitmap::GetWidth() 
{ 
	return bInfoHeader->biWidth; 
} 
 
int memBitmap::GetHeight() 
{ 
	return bInfoHeader->biHeight; 
} 
 
void memBitmap::SetWidth(int w) 
{ 
	bInfoHeader->biWidth=w; 
	BytesPerLine=bInfoHeader->biWidth*3; 
	if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4; 
} 
 
void memBitmap::SetHeight(int h) 
{ 
	bInfoHeader->biHeight=h; 
} 
 
int memBitmap::GetDispWidth() 
{ 
	return int(Scale*bInfoHeader->biWidth); 
} 
 
int memBitmap::GetDispHeight() 
{ 
	return int(Scale*bInfoHeader->biHeight); 
} 
 
COLORREF memBitmap::GetPixel(int x,int y) 
{ 
	if(flag==0) 
	{ 
		AfxMessageBox("文件尚未成功读入"); 
		return RGB(0,0,0); 
	} 
	if((x<0)||(x>=bInfoHeader->biWidth)||\ 
	   (y<0)||(y>=bInfoHeader->biHeight) ) 
	{ 
		AfxMessageBox("超出图象范围"); 
		return RGB(0,0,0); 
	} 
	y=bInfoHeader->biHeight-y-1; 
	unsigned long temp=(long)y*(long)BytesPerLine+(long)x*3; 
	if(temp>=lenth) 
	{ 
		AfxMessageBox("数据超出有效范围"); 
		return RGB(0,0,0); 
	} 
	unsigned r,g,b; 
	b=*(bitData+temp); 
	g=*(bitData+temp+1); 
	r=*(bitData+temp+2); 
	return RGB(r,g,b); 
} 
 
void memBitmap::SetPixel(int x,int y,COLORREF color) 
{ 
	if(flag==0) 
	{ 
		AfxMessageBox("文件尚未成功读入"); 
		return; 
	} 
	if((x<0)||(x>=bInfoHeader->biWidth)||\ 
	   (y<0)||(y>=bInfoHeader->biHeight) ) 
	{ 
		AfxMessageBox("超出图象范围"); 
		return; 
	} 
	y=bInfoHeader->biHeight-y-1; 
	unsigned long temp=(long)y*(long)BytesPerLine+(long)x*3; 
	if(temp>=lenth) 
	{ 
		AfxMessageBox("数据超出有效范围"); 
		return; 
	} 
	*(bitData+temp)=GetBValue(color); 
	*(bitData+temp+1)=GetGValue(color); 
	*(bitData+temp+2)=GetRValue(color); 
} 
 
void memBitmap::operator=(class memBitmap &bm) 
{ 
	if(flag==1)delete bData; 
	lenth=bm.lenth; 
	bData=new BYTE[lenth+54L]; 
	if(!bData) 
	{ 
		AfxMessageBox("内存分配失败"); 
		return; 
	} 
	CopyMemory(bData,bm.bData,lenth+54L); 
	flag=1; 
	bFileHeader=(LPBITMAPFILEHEADER)bData; 
	bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER)); 
	bBMI=(LPBITMAPINFO)bInfoHeader; 
	bitData=bData+54; 
	BytesPerLine=bm.BytesPerLine; 
	Scale=bm.GetScale(); 
} 
 
/*void memBitmap::SetScale(int bl) 
{ 
	float table[10]={0.33f,0.50f,0.67f,\ 
					 1.0f,1.33f,1.5f,1.67f,\ 
					 2.0f,2.5f,3.0f,}; 
	int CurBl=100; 
	for(int i=0;i<10;i++) 
	{ 
		if(Scale==table[i])CurBl=i; 
	} 
	if(CurBl==100) 
	{ 
		AfxMessageBox("错误的比例数据"); 
		return ; 
	} 
	if(bl==-1) 
	{ 
		if(CurBl>0)CurBl--; 
	} 
	else if(bl==1) 
	{ 
		if(CurBl<9)CurBl++; 
	} 
	else return; 
	Scale=table[CurBl]; 
}*/ 
 
BOOL memBitmap::ChangeSize(int cx,int cy) 
{ 
	int width=GetWidth(); 
	int height=GetHeight(); 
	if( (cx==width)&&(cy==height))return FALSE;	 
 
	double sx,sy;				//x和y方向的比例系数 
	memBITMAP bmp1; 
	bmp1.CreateDirect(cx,cy); 
	sx=double(cx)/(double)width; 
	sy=double(cy)/(double)height; 
	int i,j; 
 
	for(i=0;i=width-1)x=width-1; 
			if(y<=0)y=0; 
			if(y>=height-1)y=height-1; 
			if( ((int)x==0)||((int)x==width-1)||((int)y==0)||((int)y==height-1) ) 
			{ 
				COLORREF color=GetPixel((int)x,(int)y); 
				bmp1.SetPixel(i,j,color); 
			} 
			else 
			{ 
				double r1,r2,r3,r4; 
				double g1,g2,g3,g4; 
				double b1,b2,b3,b4; 
				COLORREF c1,c2,c3,c4; 
				c1=GetPixel((int)x,(int)y); 
				c2=GetPixel((int)x+1,(int)y); 
				c3=GetPixel((int)x,(int)y+1); 
				c4=GetPixel((int)x+1,(int)y+1); 
				double dis1=x-(int)x; 
				double dis2=1-x+(int)x; 
				double dis3=y-(int)y; 
				double dis4=1-y+(int)y; 
				r1=GetRValue(c1); 
				g1=GetGValue(c1); 
				b1=GetBValue(c1); 
				r2=GetRValue(c2); 
				g2=GetGValue(c2); 
				b2=GetBValue(c2); 
				r3=GetRValue(c3); 
				g3=GetGValue(c3); 
				b3=GetBValue(c3); 
				r4=GetRValue(c4); 
				g4=GetGValue(c4); 
				b4=GetBValue(c4); 
 
				int r=int(dis4*(r1*dis2+r2*dis1)+dis3*(r3*dis2+r4*dis1)); 
				if(r>255)r=255; 
				int g=int(dis4*(g1*dis2+g2*dis1)+dis3*(g3*dis2+g4*dis1)); 
				if(g>255)g=255; 
				int b=int(dis4*(b1*dis2+b2*dis1)+dis3*(b3*dis2+b4*dis1)); 
				if(b>255)b=255; 
				 
				bmp1.SetPixel(i,j,RGB((BYTE)r,(BYTE)g,(BYTE)b)); 
 
//				COLORREF color=GetPixel(int(x+0.5),int(y+0.5)); 
//				bmp1.SetPixel(i,j,color);			 
			} 
		} 
	} 
	Release(); 
	CreateDirect(cx,cy); 
	for(i=0;i=width-1)x=width-1; 
			if(y<=0)y=0; 
			if(y>=height-1)y=height-1; 
			if( ((int)x==0)||((int)x==width-1)||((int)y==0)||((int)y==height-1) ) 
			{ 
				COLORREF color=GetPixel((int)x,(int)y); 
				bmp1.SetPixel(i,j,color); 
			} 
			else 
			{ 
				double r1,r2,r3,r4; 
				double g1,g2,g3,g4; 
				double b1,b2,b3,b4; 
				COLORREF c1,c2,c3,c4; 
				c1=GetPixel((int)x,(int)y); 
				c2=GetPixel((int)x+1,(int)y); 
				c3=GetPixel((int)x,(int)y+1); 
				c4=GetPixel((int)x+1,(int)y+1); 
				double dis1=x-(int)x; 
				double dis2=1-x+(int)x; 
				double dis3=y-(int)y; 
				double dis4=1-y+(int)y; 
				r1=GetRValue(c1); 
				g1=GetGValue(c1); 
				b1=GetBValue(c1); 
				r2=GetRValue(c2); 
				g2=GetGValue(c2); 
				b2=GetBValue(c2); 
				r3=GetRValue(c3); 
				g3=GetGValue(c3); 
				b3=GetBValue(c3); 
				r4=GetRValue(c4); 
				g4=GetGValue(c4); 
				b4=GetBValue(c4); 
 
				int r=int(dis4*(r1*dis2+r2*dis1)+dis3*(r3*dis2+r4*dis1)); 
				if(r>255)r=255; 
				int g=int(dis4*(g1*dis2+g2*dis1)+dis3*(g3*dis2+g4*dis1)); 
				if(g>255)g=255; 
				int b=int(dis4*(b1*dis2+b2*dis1)+dis3*(b3*dis2+b4*dis1)); 
				if(b>255)b=255; 
				 
				bmp1.SetPixel(i,j,RGB((BYTE)r,(BYTE)g,(BYTE)b)); 
 
			} 
		} 
	} 
 
} 
 
 
bool memBitmap::CopyRect(int x1, int y1, class memBitmap &sBmp) 
{ 
	int x,y,w = GetWidth(),h = GetHeight(); 
	for(x = 0; x < w;x++) 
		for(y = 0;y < h;y++) 
			SetPixel(x,y,sBmp.GetPixel(x+x1,y+y1)); 
 
	return true; 
}