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

📄 cdibimage.cpp

📁 程序在visual c++环境下实现了图像按照输入参数进行平移旋转和在水平垂直方向上的镜像功能。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "CDibImage.h"
#include "math.h"
/////////////////////////////////////////////////////////////////////////////////
//Construction\Destruction
CDibImage::CDibImage()
{
	m_pBitbuf = NULL;
	m_dwHeight = 0;
	m_dwWidth = 0;
}

CDibImage::~CDibImage()
{
	if(m_pBitbuf) delete[] m_pBitbuf;
	m_pBitbuf = NULL;
}
//copy construction
CDibImage::CDibImage( CDibImage& Img)
{
	m_dwHeight = Img.m_dwHeight;
	m_dwWidth = Img.m_dwWidth;
	m_wBPP = Img.m_wBPP;
	
	ImgCpy( Img.m_pBitbuf, Img.m_dwHeight, Img.m_dwWidth);
}

//
//
//
void CDibImage::ImgCpy( BYTE* pSourceBmp, DWORD dwHeight, DWORD dwWidth)
{
	ImgCpy( m_pBitbuf, pSourceBmp, dwHeight, dwWidth, m_wBPP);
}
////
//
//
//
void CDibImage::ImgCpy( BYTE*& pDestBmp, BYTE* pSourceBmp, DWORD dwHeight, DWORD dwWidth,WORD wbPP)
{
	if( pDestBmp ) 
		delete []pDestBmp;
	if(wbPP == 1) wbPP = (wbPP+7)/8;
	else if(wbPP == 4) wbPP = (wbPP+1)/2;
	else if(wbPP == 8) wbPP = 1;
	else if(wbPP == 24) wbPP = 3;
	else if(wbPP == 32) wbPP = 4;
	pDestBmp = new BYTE[dwWidth*dwHeight*wbPP];

	memcpy(pDestBmp,pSourceBmp,dwHeight*dwWidth*wbPP*sizeof(BYTE));
}

//////////////////////////////////////////////////////////////
//
//
// +
void CDibImage::Add(BYTE* pDestImg, BYTE* pSourceImg)
{
}
// -
void CDibImage::Subtract(BYTE* pDestImg, BYTE* pSourceImg)
{
}
// * 
void CDibImage::Multiply(BYTE* pDestImg, BYTE* pSourceImg)
{
}


///////////////////////////////////////////////////////////////////////////////
//获取函数属性的函数
//
///////////////////////////////////////////////////////////////////////////////
//函数名:
//       IsBufferValid()
//参数:
//       无
//说明:
//       判断m_pBitbuf指向的缓冲区是否存储图像数据
///////////////////////////////////////////////////////////////////////////////
bool CDibImage::IsBufferValid()
{
	if(!m_pBitbuf) return false;
	else return true;
}
DWORD CDibImage::GetWidth()
{
	return m_dwWidth;
}
DWORD CDibImage::GetHeight()
{
	return m_dwHeight;
}
WORD CDibImage::GetBPP()
{
	return m_wBPP;
}


/////////////////////////////////////////////////////////////////////////////////
//加载和存储图行文件
//
/////////////////////////////////////////////////////////////////////////////////
//函数名:
//		LoadBmp()
//参数:
//		LPCTSTR lpFileName -需要读的文件的路径名
//说明:
//		函数根据已知文件的路径名读相应的文件
/////////////////////////////////////////////////////////////////////////////////
bool CDibImage::LoadBmp( LPCTSTR lpFileName)
{
	DWORD i,j;
	CFile File;
	if(!File.Open(lpFileName, CFile::modeRead))
	{
		AfxMessageBox("打不开");
		return false;
	}

	//读文件头
	BITMAPFILEHEADER bfh;
	File.Read(&bfh, sizeof(BITMAPFILEHEADER));

	//读信息头
	BITMAPINFOHEADER bmi;
    File.Read(&bmi, sizeof(BITMAPINFOHEADER));
	
	//填充图像的信息
	m_dwWidth = bmi.biWidth;
    m_dwHeight = bmi.biHeight;
	RGBQUAD pall[256];
	m_wBPP = bmi.biBitCount;
	DWORD bitNum= bmi.biClrUsed;
    if(m_wBPP==1) bitNum = 2;
	else if(m_wBPP==4) bitNum = 16;
    else if(m_wBPP==8) bitNum = 256;
    //读调色板信息
	if(m_wBPP) File.Read(&pall, sizeof(RGBQUAD)*bitNum);
    BYTE *pbits;//用来存放一行图像的缓冲区
    pbits = new BYTE[m_dwWidth*4];

	if(m_pBitbuf) delete[] m_pBitbuf;
	m_pBitbuf = NULL;
	DWORD dwSize = m_dwWidth*m_dwHeight*4;
	m_pBitbuf = (BYTE*) new BYTE[dwSize];
    
	
	DWORD dwPos = dwSize-m_dwWidth*4;
	//读位图文件
	File.Seek(bfh.bfOffBits, 0);
	int k;
	if(m_wBPP==1)
	{
		for(i=0;i<m_dwHeight;i++)
		{
			File.Read(pbits, (m_dwWidth+31)/32*4);//读像素到缓冲区
            for(j=0;j<m_dwWidth/8+1;j++)
			{
				for(k=0;k<8;k++)
				{
					if( j*8+k>=m_dwWidth ) continue;
					long nPos = j*8 + k;

					if(pbits[j]&(1<<(7-k)))//为1时代表黑色
					{
						m_pBitbuf[dwPos+nPos*4] = 255;
						m_pBitbuf[dwPos+nPos*4+1] =255;
                        m_pBitbuf[dwPos+nPos*4+2] =255;
						m_pBitbuf[dwPos+nPos*4+3] =255;
					}
					else//为0时代表白色
					{
						m_pBitbuf[dwPos+nPos*4] =0;
						m_pBitbuf[dwPos+nPos*4+1] =0;
						m_pBitbuf[dwPos+nPos*4+2] =0;
						m_pBitbuf[dwPos+nPos*4+3] =255;
					}					
				}
			}
			dwPos -= m_dwWidth*4;
		}
	}
	else if(m_wBPP==4)
	{
		for(i=0;i<m_dwHeight;i++)
		{
			File.Read(pbits, ((m_dwWidth+1)/2+3)/4*4);
            for(j=0;j<m_dwWidth;j++)
			{
				if(j%2) k = pbits[j/2]&0x0f;//读低4位
				else k = (pbits[j/2]&0xf0)>>4;//高四位
				m_pBitbuf[dwPos+j*4] = pall[k].rgbBlue;
				m_pBitbuf[dwPos+j*4+1] = pall[k].rgbGreen;
				m_pBitbuf[dwPos+j*4+2] = pall[k].rgbRed;
				m_pBitbuf[dwPos+j*4+3] = 255;
			}
			dwPos -=m_dwWidth*4;
		}
	}
	else if(m_wBPP==8)
	{
		for(i=0;i<m_dwHeight;i++)
		{
			File.Read(pbits, (m_dwWidth+3)/4*4);
			for(j=0;j<m_dwWidth;j++)
			{
				k = pbits[j];
				m_pBitbuf[dwPos+j*4] = pall[k].rgbBlue;
				m_pBitbuf[dwPos+j*4+1] = pall[k].rgbGreen;
				m_pBitbuf[dwPos+j*4+2] = pall[k].rgbRed;
				m_pBitbuf[dwPos+j*4+3] = 255;
			}
			dwPos -=m_dwWidth*4;
		}
	}
	else if(m_wBPP==24)
	{
		for(i=0;i<m_dwHeight;i++)
		{
			File.Read(pbits, (m_dwWidth*3+3)/4*4);
			for(j=0;j<m_dwWidth;j++)
			{
				m_pBitbuf[dwPos+j*4] = pbits[j*3];
				m_pBitbuf[dwPos+j*4+1] = pbits[j*3+1];
				m_pBitbuf[dwPos+j*4+2] = pbits[j*3+2];
				m_pBitbuf[dwPos+j*4+3] = 255;
			}
			dwPos -=m_dwWidth*4;
		}
	}
	else if(m_wBPP==32)
	{
		for(i=0;i<m_dwHeight;i++)
		{
			File.Read(pbits, m_dwWidth*4);
			for(j=0;j<m_dwWidth;j++)
			{
				m_pBitbuf[dwPos+j*4] = pbits[j*4];
				m_pBitbuf[dwPos+j*4+1] = pbits[j*4+1];
				m_pBitbuf[dwPos+j*4+2] = pbits[j*4+2];
				m_pBitbuf[dwPos+j*4+3] = pbits[j*4+3];
			}
			dwPos -=m_dwWidth*4;
		}
	}
	return true;
}

//////////////////////////////////////////////////////////////
//函数名:
//       SaveBmp()
//参数:
//       LPCTSTR lpFileName -存文件的路径名
//说明:
//       存储文件
///////////////////////////////////////////////////////////////
void CDibImage::SaveBmp( LPCTSTR lpFileName)
{
	if(IsBufferValid()==false) return;
	DWORD dwWidth,dwHeight,dwbfOffBits;
	//计算数据的偏移量
	dwbfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO)-4;
	if(m_wBPP == 1) 
	{
		dwWidth = (m_dwWidth+7)/8;
		dwbfOffBits += 2*sizeof(RGBQUAD);
	}
	else if(m_wBPP == 4) 
	{
		dwWidth = (m_dwWidth+1)/2;
		dwbfOffBits += 16*sizeof(RGBQUAD);
	}
	else if(m_wBPP == 8) 
	{
		dwWidth = m_dwWidth;
		dwbfOffBits += 256*sizeof(RGBQUAD);
	}
	else if(m_wBPP == 24) dwWidth = m_dwWidth*3;
	else if(m_wBPP == 32) dwWidth = m_dwWidth*4;
	
	//
	DWORD dwWirteWidth = (dwWidth+3)/4*4;
	DWORD dwSize = m_dwHeight*dwWidth;

	//读文件
    CFile File;
    File.Open( lpFileName, CFile::modeCreate|CFile::modeWrite);

	//创建文件头,并填充
	BITMAPFILEHEADER bfh;
	bfh.bfOffBits = dwbfOffBits;
	bfh.bfReserved1 = 0;
	bfh.bfReserved2 = 0;
	bfh.bfSize = dwSize + bfh.bfOffBits;
	bfh.bfType = 0x4d42;//位图的格式'BM'
	File.Write( &bfh, sizeof(BITMAPFILEHEADER));
	
	//创建信息头
	BITMAPINFO bmi;
	bmi.bmiHeader.biSize = sizeof(BITMAPINFO)-4;
	bmi.bmiHeader.biBitCount = m_wBPP;
	bmi.bmiHeader.biWidth = m_dwWidth;
	bmi.bmiHeader.biHeight = m_dwHeight;
	bmi.bmiHeader.biSizeImage = dwSize;
	bmi.bmiHeader.biClrImportant = 0;
	bmi.bmiHeader.biClrUsed = 0;
	bmi.bmiHeader.biCompression = 0;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biXPelsPerMeter =
		bmi.bmiHeader.biYPelsPerMeter = 0;
	bmi.bmiColors[0].rgbBlue = 
		bmi.bmiColors[0].rgbGreen = 
		bmi.bmiColors[0].rgbRed = 
		bmi.bmiColors[0].rgbReserved = 0;
	File.Write( &bmi, sizeof(BITMAPINFO));

	//写调色板
    if(m_wBPP == 1)
	{
		BYTE tmp = (BYTE) 1;
		File.Write( &tmp, 1);
		File.Write( &tmp, 1);
		File.Write( &tmp, 1);
		tmp = (BYTE) 0;
		File.Write( &tmp, 1);
		tmp = (BYTE) 1;
		File.Write( &tmp, 1);
		File.Write( &tmp, 1);
		File.Write( &tmp, 1);
		tmp = (BYTE) 0;
		File.Write( &tmp, 1);
	}
	else if(m_wBPP == 4)
	{
		for( int i=1;i<16;i++)
		{
			BYTE tmp = (BYTE) i;
			File.Write( &tmp, 1);
			File.Write( &tmp, 1);
			File.Write( &tmp, 1);
			tmp = (BYTE)255;
			File.Write( &tmp, 1);
		}
	}
	else if(m_wBPP == 8)
	{
		for( int i=1;i<256;i++)
		{
			BYTE tmp = (BYTE) i;
            File.Write( &tmp, 1);
			File.Write( &tmp, 1);
			File.Write( &tmp, 1);
			tmp = (BYTE)255;
			File.Write( &tmp, 1); 
		}
	}
	
	//写文件
	DWORD nPos = (m_dwHeight-1)*dwWidth;
    DWORD skip = (DWORD)((int)dwWirteWidth - (int)dwWidth);
	
    if(m_wBPP == 32)
	{
		for( DWORD i=0;i<m_dwHeight;i++)
		{
			File.Write( m_pBitbuf+nPos, dwWidth);
            nPos -= dwWidth;
		}
	}
	else 

⌨️ 快捷键说明

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