- 热门文章:
- · 类似画笔的绘图控件
- · 利用OpenGL实现动画效果
- · 在VC++中实现自动连续播放多媒体
- · 如何播放 WAV 文件?
- · 池塘夜降彩色雨
- · 一个对话框里的动圆
- · 用RealPlayer控件制作的播放器
- · 透明位图的显示
- · 在资源文件中加入声音资源
- · 三元光栅操作
- · 图形显示特技算法
- · 使用DirectShow驱动摄像头
位图文件读写综述
位图文件读写综述
二、位图文件读写操作
三、CFG_DIB的使用 一、位图文件结构 位图文件由三部分组成:文件头 + 位图信息 + 位图像素数据 1、位图文件头。位图文件头主要用于识别位图文件。以下是位图文件头结构的定义:
typedef struct tagBITMAPFILEHEADER { // bmfh
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
其中的bfType值应该是“BM”(0x4d42),标志该文件是位图文件。bfSize的值是位图文件的大小。 typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; 可见位图信息也是由两部分组成的:位图信息头 + 颜色表 2.1位图信息头。位图信息头包含了单个像素所用字节数以及描述颜色的格式,此外还包括位图的宽度、高度、目标设备的位平面数、图像的压缩格式。以下是位图信息头结构的定义: typedef struct tagBITMAPINFOHEADER{ // bmih DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; 下表是对结构体当中各个成员的说明:
说明:*是需要加以注意的部分,因为它们是我们在进行位图操作时经常参考的变量 (2)这个值通常为0,表示使用biBitCount确定的全部颜色,例外是使用的颜色树木小于制定的颜色深度的颜色数目的最大值。 (3)这个值通常为0,表示所有的颜色都是必需的 下图是带调色板和不带调色板的位图的简单示意图 颜色表是由颜色表项组成的,颜色表项结构的定义如下:typedef struct tagRGBQUAD { // rgbq BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; 其中需要注意的问题是,RGBQUAD结构中的颜色顺序是BGR,而不是平常的RGB。 3、位图数据。最后,在位图文件头、位图信息头、位图颜色表之后,便是位图的主体部分:位图数据。根据不同的位图,位图数据所占据的字节数也是不同的,比如,对于8位位图,每个字节代表了一个像素,对于16位位图,每两个字节代表了一个像素,对于24位位图,每三个字节代表了一个像素,对于32位位图,每四个字节代表了一个像素。
认识了位图文件的结构以后,对特定位图文件进行读写操作就显得简单了。本文附带的源代码中包含了一个能够方便进行位图读写操作的C++类。以下给出该类的使用参考,对于实现代码中的关键部分做出了讲解。 1、类的声明
class CFG_DIB : public CObject
{
public:
//默认构造函数
CFG_DIB();
//构造函数,根据图象宽和高,以及记录每个象素所需字节数来初始化
CFG_DIB(int width, int height, int nBitCounts);
virtual ~CFG_DIB();
public:
HBITMAP m_hBitmap;
LPBYTE m_lpDIBits; //DIB位的起始位置
LPBITMAPINFOHEADER m_lpBMPHdr; //BITMAPINFOHEADER信息
LPVOID m_lpvColorTable; //颜色表信息
HPALETTE m_hPalette; //条调色板
private:
DWORD m_dwImageSize; //非BITMAPINFOHEADER或BITMAPFILEHEADER的位
int m_nColorEntries; //颜色表项的个数
//显示参数
public:
CPoint m_Dest; //目的矩形域的左上角坐标
CSize m_DestSize; //显示矩形的宽度和高度
CPoint m_Src; //原矩形左下角坐标
CSize m_SrcSize; //原矩形宽度和高度
public:
void InitDestroy(); //初始化变量
void ComputePaletteSize(int nBitCounts); //计算调色板大小
void ComputeImage(); //计算图象大小
//从BMP文件中读入DIB信息
BOOL ReadFile(CFile* pFile);
//从BMP文件中读入DIB信息,与ReadFile不同的是使用CreateSection创建位图位
BOOL ReadSection(CFile* pFile, CDC* pDC = NULL);
//将DIB写入文件,保存成BMP图片格式
BOOL WriteFile(CFile* pFile);
//创建新的位图文件,根据参数width,height,nBitCounts分配内存空间
BOOL NewFile(int width, int height, int nBitCounts);
//关闭位图文件
BOOL CloseFile();
//显示位图
BOOL Display(CDC* pDC);
HBITMAP CreateBitmap(CDC* pDC); //用DIB创建DDB
HBITMAP CreateSection(CDC* pDC = NULL); //创建位图位数据,即象素数据
//如果DIB没有颜色表,可以用逻辑调色板
BOOL SetLogPalette(CDC* pDC);
//如果DIB有颜色表,可以创建系统调色板
BOOL SetWinPalette();
//把DIB对象的逻辑调色板选进设备环境里,然后实现调色板
UINT UseLogPalette(CDC* pDC);
//得到BitmapInfoHeader的大小,包含颜色表数据
int GetHeaderSize()
{
return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorEntries;
}
//得到图像的高度
int GetHeight()
{
if(m_lpBMPHdr == NULL) return 0;
return m_lpBMPHdr->biHeight;
}
//得到图像的宽度
int GetWidth()
{
if(m_lpBMPHdr == NULL) return 0;
return m_lpBMPHdr->biWidth;
}
//得到图像的大小
int GetImageSize()
{
return m_dwImageSize;
}
long GetLineBit(); //得到一行的象素数
};
2、位图的读取。 读取文件的过程中,计算出调色板大小,然后调用创建调色板函数: ComputePaletteSize(m_lpBMPHdr->biBitCount); SetWinPalette();在显示位图之前,设置调色板:if(m_hPalette != NULL) { ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE); } 4、位图的显示。位图的显示还是调用Windows的API函数来进行,需要传递的参数包括当前位图信息头,位图数据等: ::StretchDIBits(pDC->GetSafeHdc(), m_Dest.x, m_Dest.y, m_DestSize.cx, m_DestSize.cy, m_Src.x, m_Src.y, m_SrcSize.cx, m_SrcSize.cy, m_lpDIBits, (LPBITMAPINFO) m_lpBMPHdr, DIB_RGB_COLORS, SRCCOPY); 其中的m_Dest,m_DestSize,m_Src,m_SrcSize分别代表了图像在当前设备上显示的左上角坐标和范围以及需要显示的源图像的左下角坐标和范围。此处需要说明的是,位图数据的字节数组是从图像的最下面一行开始逐行想上存储的,所以用户在选取源位图的现实范围的时候需要特别注意! m_Dest,m_DestSize,m_Src,m_SrcSize需要在现实之前设置好。 5、位图的存储。位图的存储用WriteFile实现。 6、新位图的创建。新位图的创建由NewFile实现。需要的参数是位图的宽度、高度、以及位图像素占用的位数。 7、其它问题。存取位图数据的字节数组有个问题需要引起开发人员的注意:字节数组中每个扫描行的字节数必需是4的倍数,如果不足要用0补齐。 以下是处理的办法:DWORD dwBytes = ((DWORD) m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) / 32; if(((DWORD) m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) % 32) { dwBytes++; } dwBytes *= 4; m_dwImageSize = dwBytes * m_lpBMPHdr->biHeight; 这段代码按照要求算出了用于记录图像数据的字节数组的大小。 三、CFG_DIB的使用 以下是CFG_DIB的使用示例代码。 #include "fg_dib.h" CFG_DIB m_fgdib; //new file m_fgdib.NewFile(width, height, nbitnum); //open file CFile* pf; pf = new CFile; pf->Open(sFileName, CFile::modeRead); m_fgdib.ReadFile(pf); pf->Close(); delete pf; //draw BMP m_fgdib.m_Dest.x = 0; m_fgdib.m_Dest.y = 0; m_fgdib.m_DestSize.cx = m_fgdib.GetWidth(); m_fgdib.m_DestSize.cy = m_fgdib.GetHeight(); m_fgdib.m_Src.x = 0; m_fgdib.m_Src.y = 0; m_fgdib.m_SrcSize.cx = m_fgdib.GetWidth(); m_fgdib.m_SrcSize.cy = m_fgdib.GetHeight(); CDC* pDC = GetDC(); m_fgdib.Display(pDC); //close BMP m_fgdib.CloseFile();如果您在阅读文章和使用代码过程中遇到的问题,请与作者联系: 吉林省长春市西民主大街6号地球探测科学与技术学院2001级硕士研究生(130026) 欢迎访问作者的主页:Forevergis.6to23.com |
- · 在VC中调用DirectShow全屏播放视频
- · 闪屏图形特技效果的实现
- · (GDI+)Image类的序列化
- · 浮动窗体中的OpenGL多视图的实现
- · 使用GDI+进行图像处理
- · 在MFC程序中显示JPG/GIF图像
- · 如何获取屏幕上各颜色的红、绿、蓝值
- · 位图的淡入淡出显示
- · 根据文本串的长度改变窗口的大小
- · UDP轻松应用
- · 封装较完整的串口类库
- · 使用C#制作《邮件特快专递》
- · FMail文件信使 V1.0
- · 计算机活动监控系统
- · 直接用socket实现HTTP协议(下载专用)
- · Windows 实时通信技术的应用
- · 一个从网页tag里面分析url和url标题的类
- · MSComm 控件在基于单文档中的应用
- · 多线程,多接收模式串口类 LsComm 之二
- · 基于TCP的局域网多用户通信、文件传送程序详解
- · 如何限制PC机上网
- · TCP/IP学习笔记补遗
- · 如何通过Openh323开发自己的H.323协议栈
- · MSComm 控件的 Modem 通讯
- · 通过串口收发短消息(下)
- · 通过串口收发短消息(上)
- · 通过串口实时接收短消息
- · “通过串口收发短消息”的Q&A汇编
- · 使用Win32创建串口通讯程序
- · Windows2000下的Raw TCP/IP库
- · 一个简单的端口扫描程序题
- · 利用RFC868协议编写网络对时程序
- · TCP/IP学习笔记(八)
- · TCP/IP学习笔记(七)
- · TCP/IP学习笔记(六)
- · TCP/IP学习笔记(五)
- · TCP/IP学习笔记(四)
- · TCP/IP学习笔记(三)
