📄 sy0505.htm
字号:
<html>
<head>
<title>无标题文档</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p><font color="#0000FF">设备无关位图</font></p>
<p>(一)实验目的:</p>
<p>学会使用设备无关位图</p>
<p>(二)设备无关位图(DIB)简介</p>
<p>GDI位图与DIB位图是两种不同的Windows位图。GDI位图可以由MFC中的CBitmap类表示,是GDI对象的一种,该数据结构是设备有关的。DIB又称设备无关位图,它自带颜色信息(颜色表),通常以后缀为.BMP的文件形式被保留在磁盘中或者作为资源存在于程序的EXE或DLL文件中。</p>
<p>DIB包含一个二维数组,该数组的元素称为象素。一个象素可以由1、4、8、16、24、32个连续位组成。其中8位位图和24位位图比较常用。8位位图每个象素用一个字节表示,又称256色位图;24位位图每个象素用3个字节表示,又称真彩位图。</p>
<p>BMP文件结构如下</p>
<table width="676" border="1">
<tr>
<td colspan="2">
<div align="center">BITMAPFILEHEADER</div>
</td>
<td width="399">
<p> bfType(位图文件的类型,必须为BM)<br>
bfSize(位图文件的大小,以字节为单位)<br>
bfReserved1(必须为0)<br>
bfReserved2(必须为0)<br>
bfOffBits(位数据起始位置距离文件开始的字节数)</p>
</td>
</tr>
<tr>
<td rowspan="2" width="93">
<div align="center">BITMAPINFO</div>
</td>
<td width="162">
<div align="center">BITMAPINFOHEADER</div>
</td>
<td width="399">
<p>biSize(本结构大小)<br>
biWidth(按象素计算)<br>
biHeight(按象素计算)<br>
biPlanes(必须为1)<br>
biBitCount (每个像素所需的位数,1,4,8,16,24,32)<br>
biCompression (0或BI_RGB表示不压缩)<br>
biSizeImage (只在压缩图中使用)<br>
biXPelsPerMeter (水平分辨率,一般可设为0)<br>
biYPelsPerMeter (垂直分辨率,一般可设为0)<br>
biClrUsed (颜色表不足时非零)<br>
biClrImportant (重要颜色,一般可设为0)</p>
</td>
</tr>
<tr>
<td width="162">
<div align="center">颜色表</div>
</td>
<td width="399">
<p>单色DIB(2位)有2个表项<br>
16色DIB(4位)有16个表项 <br>
256色DIB(8位)有256个表项或更少<br>
真彩DIB(24位)无</p>
<p>每个表项为32位,是一个RGBQUAD类型的结构,用R、G、B三原色定义一种颜色,整个颜色表实际是一个RGBQUAD类型的数组</p>
</td>
</tr>
<tr>
<td colspan="2">
<div align="center">DIB位数据</div>
</td>
<td width="399">
<p>象素按每行每列的顺序排列<br>
从最下面的行开始排列<br>
每行扩展到4字节边界</p>
<p>按扫描行内从左到右,扫描行之间从下到上的顺序依次记录每个象素</p>
</td>
</tr>
</table>
<p>几个重要的DIB访问函数</p>
<p>SetDIBitsToDevice--------直接显示DIB<br>
StretchDIBits------------缩放显示DIB<br>
GetDIBits----------------由GDI位图构造DIB<br>
CreateDIBitmap-----------从DIB出发创建GDI位图</p>
<p>灰度</p>
<p>一个用RGB三原色表示的颜色的灰度通常用下面的公式求得:<br>
0.299 * Red + 0.587 * Green + 0.114 * Blue<br>
其中白色的灰度为255(RGB(255,255,255)),黑色的灰度为0(RGB(0,0,0))。</p>
<p>(三)实验内容:</p>
<p>阅读并编写位图处理程序</p>
<p>(四)实验步骤:</p>
<p>1. 阅读程序 <a href="l05041.rar">下载</a> (内含test.bmp)</p>
<p>该程序实现以下功能:</p>
<blockquote>
<p>1.读取256色位图文件,且biClrUsed为0(即颜色表必须为256项,每个象素1字节)<br>
2.按位图文件本身的颜色表显示该位图<br>
3.使用灰度颜色表显示该位图<br>
4.使用随机颜色表显示该位图<br>
5.像素反色(逐象素用255减去原来的值)<br>
6.颜色表反色(由于象素的颜色最终由颜色表决定,这才是真正的反色) </p>
</blockquote>
<p>主要代码在CReadDIBView::OnFileOpen()函数中,用CFile打开文件并分别将BITMAPINFO和位数据保存在类变量m_pOrgInfo和m_pBits中。</p>
<p>OnDraw中用SetDIBitsToDevice显示位图。</p>
<p>宏 #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) 用于将行的长度扩展到4字节边界(每个扫描行的字节数必须是4的整倍数)</p>
<p>程序中演示了使用VirtualAlloc/VirtualFree分配和释放内存,也可以用malloc/free或new/delete等方法替代</p>
<p>2. 参考程序示例和MSDN按要求编写一个应用程序,包括以下功能:</p>
<blockquote>
<p>1.读入位图文件<br>
2.显示<br>
3.显示为灰度图<br>
4.保存为真彩位图(24位色,BitCount=24)</p>
</blockquote>
<p>其中读入和显示可以使用前面“装入并绘制位图”一节的方法。</p>
<p>将彩色位图转换为灰度图,可以直接转换内存中的位图数据,也可以使用GetPixel和SetPixel改变DC中的位图数据。</p>
<p>真彩位图不含颜色表,每个象素3个字节分别表示R、G、B值,如果该象素只有灰度信息,则R=G=B=灰度。</p>
<p>执行文件示例<a href="l0504.exe">下载</a>。</p>
<p>(五)说明:</p>
<p>关于BITMAPFILEHEADER、BITMAPINFO、BITMAPINFOHEADER、SetDIBitsToDevice、StretchDIBits、GetDIBits、CreateDIBitmap的具体信息请查阅MSDN</p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -