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

📄 membitmap.cpp

📁 主要是应用VC进行傅立叶变换和反变换的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "stdafx.h"
#include "memory.h"
#include "memBitmap.h"

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


//以bit流形式组织数据,用于Jpeg解码
BitData::BitData()
{
	flag=FALSE;
}

BitData::~BitData()
{
}

BitData::BitData(BYTE *buf,long int lenth)
//数据流初始化
{
	if(!buf)return;		//数据指针,以字节为单位
	Data=buf;
	BufLen=lenth;
	BytePtr=0;			//在数据中的偏移
	BitPtr=0;			//在当前字节的bit指针
	step=1;				//控制流指针前进的步长
	flag=TRUE;
}

BOOL BitData::GetBit(int bits,BYTE& Value)
//从数据流中读取指定位的数据,不超过8位
{
	if(BytePtr>BufLen)
	{
		AfxMessageBox("数据出界");
		return FALSE;
	}
	if(bits>8)
	{
		AfxMessageBox("不能读取超过8位的数据");
		return FALSE;
	}
	if(flag==FALSE)
	{
		AfxMessageBox("数据尚不合法");
		return FALSE;
	}
	if(BitPtr+bits<8)		//所读数据在本字节内
	{
		Value=*(Data+BytePtr);
		Value<<=BitPtr;
		Value>>=(8-bits);
		BitPtr+=bits;
		return TRUE;
	}
	else					//所读数据超出本字节内
	{
		Value=*(Data+BytePtr);
		BytePtr++;
		Value<<=BitPtr;
		Value>>=(8-bits);
		BYTE temp=*(Data+BytePtr);
		temp>>=(16-BitPtr-bits);
		Value|=temp;
		BitPtr=bits-(8-BitPtr);
		return TRUE;
	}
}

BOOL BitData::GetBit(BYTE& Value)
//从数据流中读出一bit
{
	if(BytePtr>BufLen)
	{
		AfxMessageBox("数据出界");
		return FALSE;
	}
	if(flag==FALSE)
	{
		AfxMessageBox("数据尚不合法");
		return FALSE;
	}
	if(BitPtr==0)
	{
		step=1;
		CurByte=*(Data+BytePtr);
		if(CurByte==0xff)
		{
			BYTE nextByte=*(Data+BytePtr+1);
			if(nextByte==0)
			{
				step=2;
			}
			else
			{
				AfxMessageBox("不合法的文件标志");
				return FALSE;
			}
		}
	}
	Value=CurByte>>7;
	if(BitPtr==7)
	{
		BitPtr=0;
		BytePtr+=step;
		CurByte<<=1;
	}
	else
	{
		BitPtr++;
		CurByte<<=1;
	}
	return TRUE;
}

//***********************************************
//***********************************************
//内存位图类,从文件中读出数据,转变为24位位图格式
//可以支持Bmp的所有非压缩格式
//可以支持JFIF--Jpeg的简单的Baseline格式

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;
	}
	flag=1;
	bFileHeader=(LPBITMAPFILEHEADER)bData;
	bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER));
	bBMI=(LPBITMAPINFO)bInfoHeader;
	bInfoHeader->biWidth=ImageWidth;
	bInfoHeader->biHeight=ImageHeight;
	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)
	{
		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;
		BYTE *FileData;
		FileLenth=file.GetLength();
		lenth=FileLenth;
		FileData=new BYTE[lenth];
		bData=FileData;
		if(!FileData)
		{
			AfxMessageBox("内存分配失败");
			return FALSE;
		}
		if(!file.ReadHuge(FileData,FileLenth))
		{
			AfxMessageBox("读数据错");
			return FALSE;
		}
		flag=1;
		bFileHeader=(LPBITMAPFILEHEADER)FileData;
		bInfoHeader=(LPBITMAPINFOHEADER)(FileData+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->biBitCount!=24)
//		{
//			AfxMessageBox("本系统仅支持24位真彩图象,请自行转换格式");
//			return FALSE;
//		}
		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;j<height;j++)
			{
				for(i=0;i<width;i++)
				{
					BYTE Index=*(ImageData+j*OldBytes+i);
					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;
			delete FileData;
			return TRUE;
		}
		else if(bInfoHeader->biBitCount==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<height;j++)
			{
				for(i=0;i<width;i++)
				{
					BYTE Index=*(ImageData+j*OldBytes+i/2);
					if(i%2!=0)Index&=0xf;
					else 
					{
						Index>>=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;
			delete FileData;
			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<height;j++)
			{
				for(i=0;i<width;i++)
				{
					BYTE Index=*(ImageData+j*OldBytes+i/8);
					Index>>=(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;
			delete FileData;
			return TRUE;
		}
		else
		{
			AfxMessageBox("非法的颜色数");
			return FALSE;
		}
	}
	else if(str.Find(".jpg")!=-1)
	{
		CFile file;
		CFileException e;
		if(!file.Open(filename,CFile::modeRead,&e))
		{
			#ifdef _DEBUG  
				AfxMessageBox("文件打不开");
			#endif
			return FALSE;
		}
		file.Seek(0L,CFile::begin);
		JpegLenth=file.GetLength();
		BYTE *buf=new BYTE[JpegLenth];
		if(!buf)
		{
			AfxMessageBox("内存分配失败");
			return FALSE;
		}
		if(!file.ReadHuge(buf,JpegLenth))
		{
			AfxMessageBox("读数据错");
			return FALSE;
		}
		BOOL x=JpegToBmp(buf,JpegLenth);
		delete buf;
		file.Close();
		if(!x)Release();
		return x;
	}
	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);
	}
	file.Close();
	return TRUE;
}

void memBitmap::Display(int x,int y,CDC *dc)
{
	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)
{
	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=(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<cx;i++)
	{
		for(j=0;j<cy;j++)
		{
			double x,y;
			x=(double)i/sx;
			y=(double)j/sy;
			if(x<=0)x=0;
			if(x>=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<cx;i++)
	{
		for(j=0;j<cy;j++)
		{
			COLORREF color=bmp1.GetPixel(i,j);
			SetPixel(i,j,color);
		}
	}
	bmp1.Release();
	return TRUE;
}

void memBitmap::SetScale(float 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(bl==table[i])CurBl=i;
	}
	if(CurBl==100)
	{
		AfxMessageBox("错误的比例数据");
		return ;
	}
	Scale=table[CurBl];

⌨️ 快捷键说明

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