📄 cdibimage.cpp
字号:
#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 + -