//CDib类的实现
#include"stdafx.h"
#include<cstring>
#include "dib.h"
//**************************************************************
//无参构造函数
CDib::CDib()
{
LPSTR pDib=NULL; //指向dib位图的指针
LPSTR pPalette=NULL; //指向调色板的指针
LPSTR pPixelStart=NULL; //指向位图像素开始位置的指针
}
//**************************************************************
//拷贝构造函数
CDib::CDib(const CDib &dib)
{
DWORD dwSize=dib.GetDibSize();
pDib=(LPSTR)new char[dwSize];
//复制大片内存区域,这里调用mencpy()函数,注意第三个参数为unsigned int 类型,最大值为65535
if(dwSize<=65535)
{
memcpy((char*)pDib,(char*)(dib.pDib),dwSize);
}
else
{
char * dest, *src;
dest=(char*) pDib;
src=(char*) dib.pDib;
while(dwSize>65535)
{
memcpy(dest,src,65535);
dest+=65535;
src+=65535;
dwSize=dwSize-65535;
}
memcpy(dest,src,dwSize);
}
pPalette=pDib+sizeof(BITMAPINFOHEADER);
pPixelStart=pDib+sizeof(BITMAPINFOHEADER)+GetPaletteSize();
}
//**************************************************************
//析构函数
CDib::~CDib()
{
if(pDib!=NULL)
delete [] pDib;
}
//**************************************************************
//将file所引用的文件调入内存,如果成功执行返回true,并且给各成员指针赋值;否则返回false,
bool CDib::OpenBmpFile(CFile & file)
{
DWORD dwBitsSize;
dwBitsSize=file.GetLength(); // bmp文件的大小,单位为字节
//尝试读取文件头,并判断是否是bmp文件
BITMAPFILEHEADER bfHeader;
if(file.Read((LPSTR)&bfHeader,sizeof(bfHeader))!=sizeof(bfHeader))
{
AfxMessageBox(_T("尝试打开bmp文件头失败!"));
return false;
}
if(bfHeader.bfType!=DIB_HEADER_MAKER)
{
AfxMessageBox(_T("尝试打开的文件不是bmp文件!"));
return false;
}
//为DIB分配内存,给各成员指针赋值
pDib= (LPSTR) new char[dwBitsSize-sizeof(bfHeader)];
if(file.Read(pDib,dwBitsSize-sizeof(bfHeader))!=dwBitsSize-sizeof(bfHeader))
{
AfxMessageBox(_T("读取位图文件失败!"));
return false;
}
pPalette=pDib+sizeof(BITMAPINFOHEADER);
pPixelStart=pDib+sizeof(BITMAPINFOHEADER)+GetPaletteSize();
return true;
}
//***********************************************************************
//保存位图到file所引用的文件,如果成功执行返回true,否则返回false
bool CDib:: SaveToFile(CFile & file )
{
LPSTR lpbi;
lpbi=pDib;
if(!IS_WIN30_DIB(lpbi))
{
AfxMessageBox(_T("要保存的不是win3.0DIB,本程序不支持!"));
return false;
}
//填充文件头
BITMAPFILEHEADER bmfHeader;
bmfHeader.bfType=DIB_HEADER_MAKER;
//计算文件大小
DWORD dwBitsSize=(*(LPDWORD)(lpbi))+GetPaletteSize();
long width=(((((BITMAPINFOHEADER*)pDib)->biWidth)*(((BITMAPINFOHEADER*)pDib)->biBitCount)+31)/32)*4; //计算一行所占的字节数
dwBitsSize=dwBitsSize+width*(((BITMAPINFOHEADER*)pDib)->biHeight);
bmfHeader.bfSize=dwBitsSize+sizeof(BITMAPFILEHEADER);
bmfHeader.bfReserved1=0;
bmfHeader.bfReserved2=0;
bmfHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+(*(LPDWORD)(lpbi))+GetPaletteSize();
//尝试写文件
try
{
file.Write((LPSTR)&bmfHeader,sizeof(BITMAPFILEHEADER));
file.Write(pDib,dwBitsSize);
}
catch(CFileException *e)
{
e->ReportError();
e->Delete();
return false;
}
return true;
}
//**********************************************************************
//将图片显示到设备描述表的固定位置,(x,y)指的是图片左上角要显示的位置,这个函数应该包含创建调色板的模块
bool CDib::Show(CDC & dc,int x,int y)
{
int i=GetPaletteSize();
if(i!=0)
{
//如果不是真彩色图像
//创建调色板
WORD wColors=GetColorNumInPal();
LOGPALETTE *pLP=(LOGPALETTE *)new char[sizeof(LOGPALETTE)+(wColors-1)*sizeof(PALETTEENTRY)];
pLP->palVersion=0x300;
pLP->palNumEntries=wColors;
for(int i=0;i<wColors;i++)
{
pLP->palPalEntry[i].peRed=((BITMAPINFO*)pDib)->bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen=((BITMAPINFO*)pDib)->bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue=((BITMAPINFO*)pDib)->bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags=0;
}
CPalette palette;
palette.CreatePalette(pLP);
//绘图
HPALETTE hPal=(HPALETTE)(&palette)->m_hObject;
HPALETTE hOldPal=::SelectPalette((HDC)dc,hPal,TRUE);
::SetStretchBltMode((HDC)dc,COLORONCOLOR);
if(::StretchDIBits((HDC)dc,x,y,GetWidth(),GetHeight(),0,0,GetWidth(),GetHeight(),pPixelStart,(BITMAPINFO*)pDib,DIB_RGB_COLORS,SRCCOPY)==GDI_ERROR)
{
AfxMessageBox(_T("绘制DIB位图失败!"));
return false;
}
::SelectPalette((HDC)dc,hOldPal,TRUE);
delete [] pLP;
}
else
{
//绘制真彩色图像
if(::StretchDIBits((HDC)dc,x,y,GetWidth(),GetHeight(),0,0,GetWidth(),GetHeight(),pPixelStart,(BITMAPINFO*)pDib,DIB_RGB_COLORS,SRCCOPY)==GDI_ERROR)
{
AfxMessageBox(_T("绘制DIB位图失败!"));
return false;
}
}
return true;
}
//**********************************************************************
//赋值运算符重载
CDib CDib:: operator =(const CDib & dib)
{
DWORD dwSize=dib.GetDibSize();
pDib=(LPSTR)new char[dwSize];
//复制大片内存区域,这里调用mencpy()函数,注意第三个参数为unsigned int 类型,最大值为65535
if(dwSize<=65535)
{
memcpy((char*)pDib,(char*)(dib.pDib),dwSize);
}
else
{
char * dest, *src;
dest=(char*) pDib;
src=(char*) dib.pDib;
while(dwSize>65535)
{
memcpy(dest,src,65535);
dest+=65535;
src+=65535;
dwSize=dwSize-65535;
}
memcpy(dest,src,dwSize);
}
pPalette=pDib+sizeof(BITMAPINFOHEADER);
pPixelStart=pDib+sizeof(BITMAPINFOHEADER)+GetPaletteSize();
return *this;
}
//**********************************************************************
//重载下标运算符,方便处理过程中用下标访问图像像素值
//注意此下标访问只适合24位灰度图像
CRgb* CDib::operator [](const unsigned i)
{
DWORD dwBytes=(((BITMAPINFOHEADER*)pDib)->biSizeImage)/(((BITMAPINFOHEADER*)pDib)->biHeight);
CRgb *p=(CRgb*)((char*)pPixelStart+(GetHeight()-i-1)*dwBytes);
return p;
}
//**********************************************************************
//返回一个像素所占的位数
unsigned CDib::GetBitsOfPixel() const
{
return ((BITMAPINFOHEADER*)pDib)->biBitCount;
}
//**********************************************************************
//返回调色板中的颜色种数,返回的只是实际所用颜色数的近似值,一般会稍微大于实际所用颜色种数
unsigned CDib::GetColorNumInPal()const
{
if(((BITMAPINFOHEADER*)pDib)->biClrUsed!=0)
return ((BITMAPINFOHEADER*)pDib)->biClrUsed;
int i=((BITMAPINFOHEADER*)pDib)->biBitCount;
switch(i)
{
case 1:
return 2;
break;
case 4:
return 16;
break;
case 8:
return 256;
break;
default:
return 0;
break;
}
}
//**********************************************************************
//返回图像宽度,以像素为单位
unsigned CDib::GetWidth() const
{
return ((BITMAPINFOHEADER*)pDib)->biWidth;
}
//**********************************************************************
// 返回图像高度,以像素为单位
unsigned CDib::GetHeight() const
{
return ((BITMAPINFOHEADER*)pDib)->biHeight;
}
//**********************************************************************
//返回调色板大小,以字节为单位
unsigned CDib::GetPaletteSize() const
{
return GetColorNumInPal()*sizeof(RGBQUAD);
}
//***********************************************************************
//返回位图所占字节,不包括文件头
DWORD CDib::GetDibSize() const
{
DWORD dwBitsSize=(*((LPDWORD)(pDib)))+GetPaletteSize();
DWORD width=(((((BITMAPINFOHEADER*)pDib)->biWidth)*(((BITMAPINFOHEADER*)pDib)->biBitCount)+31)/32)*4; //计算一行所占的字节数
dwBitsSize=dwBitsSize+width*(((BITMAPINFOHEADER*)pDib)->biHeight);
return dwBitsSize;
}
没有合适的资源?快使用搜索试试~ 我知道了~
DIB类(基于MFC的设备无关位图类)
共2个文件
cpp:1个
h:1个
5星 · 超过95%的资源 需积分: 14 73 下载量 178 浏览量
2009-11-27
11:02:23
上传
评论 1
收藏 3KB RAR 举报
温馨提示
这是我个人写的CDib类,已经实现读取,存储,显示BMP位图,方便易用,适合图像处理初学者(基于MFC).
资源推荐
资源详情
资源评论
收起资源包目录
dib.rar (2个子文件)
dib.h 2KB
dib.cpp 7KB
共 2 条
- 1
资源评论
- 易阳2013-07-11可以用,非常感谢
- wuweiweiwei2013-03-02可以用,感谢
- LiuvsShuai2014-07-02确实只适合初学者用,对位图的操作不够全面
ericming200409
- 粉丝: 133
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功