第9章 位图资源的应用

特殊说明:版权归个人所有,请勿转载,谢谢合作。

位图对于在日常应用中,使用较为频繁,很多界面丰富、美观的程序,大部分以位图方式拼凑出来的,本章节通过位图的应用,了解位图的基本原理与使用方法。

在计算机中显示的图形一般可以分为两大类:矢量图和位图。

矢量图使用直线和曲线来描述图形,这些图形的元素是一些点、线、矩形、多边形、圆和弧线等等,它们都是通过数学公式计算获得的。例如一幅花的矢量图形实际上是由线段形成外框轮廓,由外框的颜色以及外框所封闭的颜色决定花显示出的颜色。由于矢量图形可通过公式计算获得,所以矢量图形文件体积一般较小。矢量图形最大的优点是无论放大、缩小或旋转等不会失真。最大的缺点是难以表现色彩层次丰富的图像效果。

位图,又称光栅图,一般用于照片品质的图像处理,是由许多像小方块一样的像素组成的图形。由像素的位置与颜色值表示,能表现出颜色阴影的变化。简单说,位图就是以无数的色彩点组成的图案,当无限放大时会看到一块一块的像素色块,效果会失真。

位图是一个图形对象,例如照片、图片和绘画。可以把它们绘制到一个窗口或对话框中去。如图9.1所示。

  • 图9.1 位图的应用

 

计算机视频系统的核心是内存。内存中包含的数据,代表显示器上出现的图案。称这个内存为视图内存。位图代表类似视频内存RAM区域,位图内存不可见,视频内存是可见的。位图分配的RAM代表一个矩形区域,这个区域的内存句柄被称为HBITMAP。如果将位图内存加载到视频内存中,在显示器上将出现图形。通常情况下,Win32 SDK使用CreateBitmap函数或CreateCompatibleBitmap函数来实现位图的创建,使用LoadBitmap函数实现加载。CreateBitmap函数原型如下:

HBITMAP CreateBitmap(
  int nWidth,         // bitmap width, in pixels
  int nHeight,         // bitmap height, in pixels
  UINT cPlanes,       // number of color planes used by device
  UINT cBitsPerPel,    // number of bits required to identify a color
  CONST VOID *lpvBits // pointer to array containing color data
);

 

参数nWidth,指定位图的宽度,单位为像素。

参数nHeight,指定位图的高度,单位为像素。

参数cPlanes,指定该设备使用的颜色位面数目。

参数cBitsPerPel,指定用来区分单个像素点颜色的位数(比特数目)。

参数lpvBits,指向颜色数据数组指针。这些颜色数据用来设置矩形区域内像素的颜色。矩形区域中的每一扫描线必须是双字节的整数倍(不足部分以0填充)。如果该参数为NULL,将不对新生成的位图进行初始化。

 

如果函数成功,那么返回值是位图的句柄;如果失败,那么返回值为NULL。若想获取更多错误信息,请调用GetLastError函数。在创建完位图之后,可以通过使用SelectObject函数把它选入到设备环境中。尽管函数CreateBitmap可以用来创建彩色位图,但由于性能方面的原因,应用程序使用CreateBitmap函数来创建单位色位图,创建彩色位图应该使用函数CreateCompatibleBitmap。当由CreateBitmap创建而返回的彩色位图被选入到设备环境时,系统必须确保选入进去的设备环境格式与位图匹配。由于函数CreateComapatbleBitmap获取设备环境,所以它返回的位图与指定的设备环境有相同的格式。由于这个原因,对SelectObject的后续调用都要比从CreateBitmap函数创建返回的彩色位图调用快。如果位图是单色的,那么对于目标设备环境而言,0表示前景颜色,而1表示背景颜色。

CreateCompatibleBitmap函数创建与指定的设备环境相关的设备兼容的位图,函数原型如下:

HBITMAP CreateCompatibleBitmap(
  HDC hdc,         // handle to device context
  int nWidth,      // width of bitmap, in pixels
  int nHeight      // height of bitmap, in pixels
);

 

参数hdc,设备环境句柄。

参数nWidth,指定位图的宽度,单位为像素。

参数nHeight,指定位图的高度,单位为像素。

 

如果函数执行成功,那么返回值是位图的句柄;如果函数执行失败,那么返回值为NULL。若想获取更多错误信息,请调用GetLastError。由CreateCompatibleBitmap函数创建的位图的颜色格式与由参数hdc标识的设备的颜色格式匹配。该位图可以选入任意一个与原设备兼容的内存设备环境中。由于内存设备环境允许彩色和单色两种位图。因此当指定的设备环境是内存设备环境时,由CreateCompatibleBitmap函数返回的位图格式不一定相同。然而为非内存设备环境创建的兼容位图通常拥有相同的颜色格式,并且使用与指定的设备环境一样的色彩调色板。当不再需要这个位图的时候,调用DeleteObject删除它。

LoadBitmap函数从应用程序的的可执行文件中加载指定的位图资源。函数原型如下:

HBITMAP LoadBitmap(
  HINSTANCE hInstance,    // handle to application instance
  LPCTSTR lpBitmapName    // address of bitmap resource name
);

 

参数hInstance,指向模块实例的句柄。该模块的可执行文件包含了要加载的位图。

参数lpBitmapName,指向字符串(以NULL结束)指针。该字符串包含了要加载的位图资源名称。另外一种方式就是该参数可以由低位字是资源标识符、高位字为0位形式组成。可以使用宏MAKEINTRESOURCE来创建这个参数值。

如果函数执行成功,则返回值是指向指定位图的句柄。如果函数执行失败,那么返回值是NULL。

位图加载成功后,还需要使用BitBlt函数来实现位图的绘制,该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。函数原型如下:

BOOL BitBlt(
  HDC hdcDest,			// handle to destination device context
  int nXDest,			// x-coordinate of destination rectangle's upper-left 
          			// corner
  int nYDest,			// y-coordinate of destination rectangle's upper-left 
          			// corner
  int nWidth,			// width of destination rectangle
  int nHeight,			// height of destination rectangle
  HDC hdcSrc,			// handle to source device context
  int nXSrc,			// x-coordinate of source rectangle's upper-left 
          			// corner
  int nYSrc,			// y-coordinate of source rectangle's upper-left 
          			// corner
  DWORD dwRop			// raster operation code
);

 

参数hdcDest,指向目标设备环境的句柄。

参数nXDest,指定目标矩形区域左上角的X轴逻辑坐标。

参数nYDest,指定目标矩形区域左上角的Y轴逻辑坐标。

参数nWidth,指定源和目标矩形区域的逻辑宽度。

参数nHeight,指定源和目标矩形区域的逻辑高度。

参数hdcSrc,指向源设备环境的句柄。

参数nXSrc,指定源矩形区域左上角的X轴逻辑坐标。

参数nYSrc,指定源矩形区域左上角的Y轴逻辑坐标。

参数dwRop,指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。表9.1所示,为常见的光栅操作代码。

 

  • 表9.1 光栅操作代码
描述
BLACKNESS 表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域(对缺省的物理调色板而言,该颜色为黑色)
DSTINVERT 目标矩形区域颜色取反操作
MERGECOPY 将源位图和模板执行与操作
MERGEPAINT 将源位图和模板执行或操作
NOTSRCCOPY 在复制之前将源位图执行取反操作
NOTSRCERASE 将源位图和目标位图执行或操作后,再执行取反操作
PATCOPY 将特定的模板拷贝到目标位图上
PATINVERT 将模板和目标位图执行异或操作
PATPAINT 通过使用布尔OR(或)操作符将源矩形区域取反后的颜色值与特定模板的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并
SRCAND 将源位图与目标位图执行与操作
SRCCOPY 将源位图原样复制到目标位图
SRCERASE 将目标位图取反操作后,再与源位图执行与操作
SRCINVERT 将源位图与目标位图执行异或操作
SRCPAINT 将源位图与目标位图执行或操作
WHITENESS 使用与物理调色板中索引1有关的颜色填充目标矩形区域(对于缺省物理调色板来说,这个颜色就是白色)

 

在使用BitBlt函数时,要用到兼容DC。兼容的DC指的不是具体的图形设备,而是虚拟的设备,可以在兼容DC中执行绘图操作,通过图形拷贝函数快速拷贝到HDC中,实现图像的高速显示。显示位图需要六个步骤:

  • 创建兼容DC;
  • 加载位图;
  • 选入位图;
  • 执行BitBlt函数,将兼容DC中的图形拷贝到当前设备环境中;
  • 选出位图;
  • 删除位图。

 

【例9-1】实现了位图的加载,在位图加载之前,需要将位图以资源的方式加入到工程中。在资源界面中选择【Bitmap】项,点击【Import…】按钮,导入位图。如图9.2所示。

  • 图9.2 选择位图

 

在导入资源目录选择界面,首先,点击【文件类型】处,选择“所有文件(*.*)”;其次,在【查找范围】处选择位图存放位置,以桌面“inputbmp.bmp”为例;点击【Import】按钮导入。如图9.3所示。

  • 图9.3 选择导入文件

 

导入后,会出现一个提示,点击【确定】按钮即可。出现这个提示的原因是,导入的位图大于256色,VC6.0不能对它进行编辑,所弹出的提示信息。如图9.4所示。

  • 图9.4 提示信息(位图大于256色)

 

导入完成后,更改位置的ID。更改后的ID为“IDB_FACE_BMP”。如图9.5所示。

  • 图9.5 修改位图ID

 

位图也是绘图的一种,通常将绘制代码写在WM_PAINT消息中的BeginPaint函数与EndPaint函数之前。代码如下所示。

  // 图形绘制事件
case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);

  {
    HBITMAP  hOldbmp,hbmp = NULL;
    HDC hmdc =CreateCompatibleDC(hdc);
    hbmp = LoadBitmap(g_hIns, MAKEINTRESOURCE(IDB_FACE_BMP));
    hOldbmp = (HBITMAP)::SelectObject(hmdc ,hbmp);
    ::BitBlt(hdc,0,0,283,195,hmdc, 0,0,SRCCOPY);
    ::SelectObject(hmdc,hOldbmp);
    DeleteDC(hmdc);
  }

  EndPaint(hWnd, &ps);
  break;

 

首先,CreateCompatibleDC函数通过当前的hdc,创建新的兼容DC,并通过LoadBitmap函数将刚刚加入到工程中的位图资源IDB_FACE_BMP进行加载;

其次,使用SelectObject函数选入位图;

现次,使用BitBlt函数将位图原样复制到当前DC中(位置的大小为283×195);

最后,使用SelectObject函数还原系统位图,并使用DeleteDC函数删除创建的兼容DC。

 

 

转载请附上原文出处链接及本声明
李老师的博客 » 第9章 位图资源的应用

发表评论

提供最优质的文章集合

立即查看 了解详情