位图图像基础

一、图像的分类:根据图想记录方式的不同,分为模拟图像和数字图像。模拟图像是吐过某种物理量的强弱变化来记录图像各点的亮度信息。数字图像完全用数字来记录图像亮度信息。
二、屏幕分辨率:平时所说的1024*768,屏幕上每行像素为1024个,共768行。颜色表存储每个像素的颜色。24位真彩色位图没有颜色表。
三、计算机常显示的图像:二值图像,灰度图像,伪彩色和真彩色图像。1、灰度图像只有亮度信息,么有颜色信息。并用一个字节处女、存储灰度值,范围即0~255 2、彩色图像用rgb三基色来表示,每个基色用一个字节来表示。则每个像素占3个字节。黑白图像每个像素占一位,颜色表也就有2^1=2个表项,整个颜色表的大小为2*sizeof(RGBQUAD)=2*4=8个字节,16色图每个像素占4位。256色即灰度图每个像素占8位。真彩色图每个像素占24位。灰度图像的颜色表是一个256个表项的RGBQUAD结构体数组,而每个RGBQUAD中的R、G、B分量的值是相等的。因此只有图像亮度信息,没有颜色信息,因而显示出的灰度图像也就没有颜色了。
四、bmp文件:BMP文件是Windows操作系统所推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,所以称为位图(bitmap)文件,因其文件扩展名为BMP,故称为BMP文件格式,简称BMP文件。BMP图像文件被分成4个部分:位图文件头(Bitmap File Header)、位图信息头(BitmapInfoHeader)、颜色表(Color Map)和位图数据(即图像数据,Data Bits或Data Body)。具体不再讨论。
五、GDI位图和DIB位图。GDI位图和DIB位图是两种不同的Windows位图,GDI位图是MFC的CBitmap类表示的,在CBitmap类的对象中,包含了一种和Windows的GDI模块有关的Windows数据结构BITMAP,该结果是与设备有关的,应用程序可以得到GDI位图数据的一个备份,但其中位图的安排完全依赖于显示设备。在同一台机器中,我们可以将GDI位图在不同的应用程序中任意地传送,但由于GDI位图对设备的依赖性,因此通过磁盘或调制解调器对它们进行传送没有太大的意义。GDI位图是由保存位图数据的BITMAP结果定义的,BITMAP定义如下:

typedef struct tagBITMAP{
LONG bmType; //位图类型,必须为0
LONG bmWidth; //位图宽度
LONG bmHeight; //位图高度
LONG bmWidthBytes; //每一行像素所在的byte数
WORD bmPlanes; //颜色平面数
WORD bmBitsPixel; //像素的位数
LPVOID bmBits; //位图内存指针
}BITMAP;

  DIB(Device-indepentent bitmap)位图是另外一种格式的位图,它完全解决了位图传送问题,任何运行Windows的机器都可以对DIB进行处理,它通常以后缀为BMP的文件形式保留在磁盘中,当BMP文件从磁盘文件中读出来以后,它通常被转成GDI位图,但必要的时候程序可直接利用DIB格式进行工作。
具体DIB和GDI位图的使用见 http://book.51cto.com/art/200708/54823.htm
1.使用GDI位图:
  使用GDI位图之前必须创建它,然后把它选进设备环境中,当使用完了以后,还得将它从设备环境中取出来,把它删掉,这是使用GDI位图的过程。
(1)生成位图
   MFC提供了管理位图的CBitmap类,因此生成位图的第一步就是声明这个类的实例,如:
CBitmap m_Bitmap;
  位图对象通常声明为一个主程序类(如视图类)的数据成员。一旦声明CBitmap对象,必须调用适当的CBitmap成员函数将对象初始化。下面介绍如何初始化CBitmap对象,一是调用LoadBitmap成员函数装入程序资源中的位图数据,一是调用成员函数Create CmpatibleBitmap生成空位图,运行程序时再画所要的图形。
将位图作为程序资源就可以利用交互式位图编辑程序来设计位图,如Visual C++图形编辑器和Windows 98 Paint等其他绘图程序,因此这种方法特别适用于生成相对复杂的或非几何图形,它们很难绘图函数生成。
为了用Visual C++图形编辑器设计位图,选择“Insert”菜单的“Resource”命令或按快捷键“Ctrl+R”,并在“Insert Resource”对话框中选择资源类型Bitmap,然后用Visual C++打开图形编辑器中的新位图窗口,之后可以设计所要的位图图形。
生成新位图时,Visual C++赋值默认标识符。方法是:双击位图窗口,在“Bitmap Properties”对话框中选择“General”标签,并在ID文本框中输入新的标识符。
无论在Visual C++图形编辑器中设计位图或是从位图文件引入,该位图都会加入程序资源。程序运行时,可以装入该位图并用它初始化位图对象。为此调用CBitmap成员函数LoadBitmap,例如:
CBitmap m_Bitmap;
m_Bitmap.LoadBitmap(IDB BITMAP1);

LoadBitmap的参数是位图在图形编辑器中生成或从位图文件引入时赋予的标识符。
(2)初始化位图
既然可以在编辑器中设计位图,也可以在程序运行时初始化一个空位图并用MFC绘图函数在位图中画出所要的图案。步骤如下:
初始化空位图。
生成内存设备环境对象。
将位图选入内存设备环境对象。
在位图中对内存设备环境对象调用CDC绘图函数画出所要图形。
初始化空位图可调用CeateCompalibeBitmap函数,例如:
CBitmap m_Bitmap;
CClient DC dc(this);
m_Bitmap.CreatCompalibeBitmap(&dc,32,32);
函数CeateCompalibeBitmap的第一个参数是设备环境对象的地址,生成的位图将与这个对象相联系的设备兼容,第二、三个参数分别是位图的宽度和高度,单位是图素。
调用CeateCompalibeBitmap时,Windows保留一块内存给位图。这个位图中存放的图素值最初是未定的,必须用绘图函数生成所要的图形。但在位图内画图前,要生成与位图相联系的设备环境对象,这就是内存设备环境对象。为了生成内存设备环境对象,先要声明CDC类的实例,再调用CDC的成员函数CreateCompatibleDC,例如:
CClient DC dc(this);
CDC MemDC;
m_Bitmap.CreatCompalibeBitmap(&dc,32,32);
MemDC.CreateCompatibleDC(&dc);
函数CreateCompatibleDC的参数是设备环境对象的地址。接着调用CDC的成员函数SelectObject将位图对象选入内存设备环境对象,例如:
MemDC.SelectObject(7m_Bitmap);
现在可以对内存设备环境对象调用CDC绘图函数在位图内画所要的图形了。
2.显示和处理位图:

生成所需的位图之后,把位图显示在窗口上或其他设备上才是最终目的。MFC的CDC类提供了三个传送图形数据块的灵活而有效的函数PatBlt,BitBlt和StretchBlt。生成图形时可用这些函数,复制图形数据块和用简单或复杂的方法修改图形数据(如传递颜色或翻折图形)时也用这些函数。这些函数可用于将图形数据从同一设备显示表面的一个位置复制到另一个位置,也可用于在不同设备间或设备与位图间复制图形数据。
PatBlt可用通过CDC类的成员函数PatBlt画矩形区。在位操作环境中,当前刷通常指当前图案。尽管也可通过调用CDC::FillRect用当前图案填充区域,但PatBlt函数更加灵活,其原型如下:
BOOL patBlt(int x, int y, int nWidth, int nHeight , DWORD dwRop) ;
前两个参数指定所画矩形区左上角的逻辑坐标,后两个参数按逻辑单位指定这个区的宽和高,最后一个参数是光栅操作码。光栅操作码提供了PatBlt的灵活性,它指定图案中的每个图素与目标地点的当前图素的组合方式,产生最后的目标图素颜色。
BitBlt函数可以把图形数据块从一个位置传送到另一位置,源位置和目标位置可以在同一设备(或位图)上,也可以在不同设备上,其原型如下:
BOOL BitBlt(int x, int y, int nWidth, int nHeight ,CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) ;
前两个参数指定传送目标位置左上角的逻辑坐标,后两个参数指定传送的数据块逻辑尺寸。第五个参数pSrcDC是源设备环境对象的指针,第六、七个参数是源设备中位图的左上角逻辑坐标,最后一个参数是光栅操作码。
BitBlt将图形数据块从一个与第五个参数表示的环境对象相联系的设备复制到与调用函数的环境对象相联系的设备上。
StretchBlt是这三个位操作函数中最灵活的,它可用于完成BitBlt能完成的所有操作,还可以在传送时改变数据块的大小和将块翻转(水平、垂直或双向),其原型如下:
BOOL StretchBlt(int x, int y, int nWidth, int nHeight ,CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth ,int nSrcHeight, DWORD dwRop) ;
StretchBlt除了比BitBlt增加两个指明源位图宽和高的参数外,其他同BitBlt一样。这样StretchBlt可用于指定源块和目标块的大小,而BitBlt只能指定一个块的大小。如果目标大小小于源大小,则图形压缩,如果目标大小大于源大小则图形扩大。如果nWidth和nSrcWidth的符号不同,则目标图形是源图的水平镜像。同样,如果nHeight和nSrcHeight符号相反,则目标图形是源图的垂直镜像。
举例::

CBitmap bitmap;

    //设备环境类对象
    CDC dcMemory;

    //加载资源位图
    bitmap.LoadBitmap(IDB_building);

    //创建内存设备环境
    dcMemory.CreateCompatibleDC(pDC);

    //把位图选进内存设备环境,并保存旧的GDI位图对象,
    CBitmap *oldbitmap=dcMemory.SelectObject(&bitmap);

    //显示
    pDC->BitBlt(0,0,400,300, &dcMemory,0,0,SRCCOPY);

    //释放bitmap,恢复原GDI位图
    dcMemory.SelectObject(oldbitmap);

3.使用DIB位图:

前面介绍的GDI位图都是与设备有关的,移植性很差。如果要将位图保存在文档中,以便其他机器能够对它进行读取,则必须使用与设备无关的格式。几乎所有的绘图应用程序的根据都是以DIB格式来处理BMP磁盘文件的。DIB格式可支持单色、16色及256色位图,也支持24位彩色位图。为了节省磁盘空间,DIB格式还可对16色和256色位图进行压缩。
4.BMP文件的组成:
BMP图像文件结构可分为三部分:表头、调色板和图像数据。只有全彩色BMP图像文件内没有调色板数据,其余不超过256种颜色的图像文件都必须设定调色板信息,即使是单色BMP图像文件也不例外。
(1)BMP表头数据
Windows把BMP图像文件表头细分为两组数据结构:BITMAPFILEHEADER和BITMAPINFOHEADER,如果还需要调色板数据,则放在表头之后,两数据结构的内容如下:

位图图像基础_第1张图片
位图图像基础_第2张图片
(2)调色板数据
Windows将BMP图像文件的调色板数据结构命名为RGBQUAD,该结构描述组成一个颜色的红、绿、蓝相对强度值。其数据结构如下:
位图图像基础_第3张图片
还有一个重要的数据结构BITMAPINFO,该结构由前面介绍的BITMAPINFOHEADER和RGBQUAD结构组成,它提供了WindowsDIB的大小和颜色的完整定义。因此也可这样说,DIB位图由两个不同的部分组成:描述位图大小和颜色的BITMAPINFO结构和定义位图像素的字节数组,BITMAPINFO的结构如下:
这里写图片描述
(3)不压缩图像数据
BMP图像文件对图像数据有三种处理方式:
不压缩数据,任何BMP图像文件都能以这种方式处理。
RLE4压缩法,这是专用于16色图像数据的压缩方法。
RLE8压缩法,只用于压缩处理256色图像数据。
不压缩图像数据是BMP图像文件的通用处理方式。虽然这种做法会使得BMP图像文件的大小大与其他有压缩处理的图像文件,但是少了压缩和解压缩的过程,也让BMP图像文件的读或存取文件的速度超过压缩处理的图像文件。既然没有了压缩处理的文件,只要了解图像数据的排列及存储方式,必能正确地处理未压缩数据的BMP图像文件。
BMP图像文件内的图像数据的排列顺序是以图像的左下角为起点,按照由左至右,由下至上的次序,将图像数据一点一点存入文件的。图像数据的存储方式是:单色图像是以一个字节记录8点;16色图像是一个字节记录两点,左边四个Bits存第一点,右边四个Bits存第二点;256色图像是一个字节记录一点;全彩色图像则是三个字节记录一点,而以RGB,RGB,RGB…的次序排列下来。除此之外,BMP文件规定文件内每行字节的个数必须是4的倍数,若未达到4的倍数,必须在每行的末端加上几个字节,以补足差额。
5.编写DIB类:
由于MFC未提供DIB类,用户在使用DIB时将面临繁重的Windows API编程任务。幸运的是,Visual C++提供了一个较高层次的API,简化了DIB的使用。这些API函数实际上是由MFC的DibLook例程提供的,它们位于DibLook目录下的dibapi.cpp、myfile.cpp和dibapi.h文件中,主要包括:
ReadDIBFile:把DIB文件读入内存。
SaveDIB:把DIB保存到文件中。
CreateDIBPalette:从DIB中创建一个逻辑调色板。
PaintDIB:显示DIB。
DIBWidth:返回DIB的宽度。
DIBHeight:返回DIB的高度。

你可能感兴趣的:(位图)