实验数字图像的输入输出显示.docx
- 文档编号:11251423
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:24
- 大小:22.72KB
实验数字图像的输入输出显示.docx
《实验数字图像的输入输出显示.docx》由会员分享,可在线阅读,更多相关《实验数字图像的输入输出显示.docx(24页珍藏版)》请在冰豆网上搜索。
实验数字图像的输入输出显示
实验一数字图像的输入、输出、显示
一、实验目的
1.了解BMP图像的基本格式;
2.了解BMP图像文件的打开和存储;
3.利用VC编写BMP图像的打开和存储的程序;
4.在微机上调试程序。
二、实验原理
1.BMP图像文件格式
BMP图像文件是MicrosoftWindows所规定的图像文件格式。
随着Windows的风行全球,BMP图像文件也就成为PC机上流行的图像文件格式。
BMP图像文件具有下列六项特色。
(1)文件结构只能存放一幅图像。
(2)可以存储单色、16色、256色和全彩色四种图像数据。
(3)图像数据可选择压缩或不压缩处理
(4)Windows设计了两种压缩方式:
RLE4和RLE8。
RLE4处理16色图像数据;而RLE8则是压缩256图像数据。
(5)图像数据排列顺序,与一般图像文件有所不同。
(6)调色板的数据结构特殊。
(1)BMP文件内容
BMP图像文件的文件结构如图1-1所示,可分为三部分:
表头、调色板和图像数据。
表头长度固定为54个字节。
只有全彩色BMP图像文件内没有调色板数据,其余不超过256种颜色的图像文件都必须设定调色板信息,即使是单色BMP图像文件也不例外。
BMP表头数据
调色板数据
图像数据
图1-1BMP文件结构
BMP图像文件的文件结构设计的颇为简单,只允许每个文件存放一幅图像。
(a)BMP表头数据
Windows把BMP图像文件表头细分成两组数据结构,第一组命名为位图文件头(BITMAPFILEHEADER),第二组称作位图信息头(BITMAPINFOHEADER),如果还需要调色板数据,则存放在表头之后。
以下分别说明BITMAPFILEHEADER(见表1)和BITMAPINFOHEADER(见表2)这两组数据结构的内容。
表1BITMAPFILEHEADER数据内容(14个字节)
数据地址
数据类型
数据名称
0
unsignedchar
bfType[2]
2
unsignedlong
bfSize
6
unsignedint
bfReserved1
8
unsignedint
bfReserved2
10
unsignedlong
bfOffBits
bfType[2]:
内容固定为“BM”(0x42及0x4D),作为文件辨识之用,表示这个文件是BMP图像文件。
bfSize:
BMP图像文件的文件大小。
bfReserved1和bfReserved2:
两个都是保留值,没有任何作用,其值都设定为0。
bfOffBits:
指示图像数据文件内的起始地址。
表2BITMAPINFOHEADER数据内容(40个字节)
数据地址
数据类型
数据名称
14
unsignedlong
biSize
18
unsignedlong
biWidth
22
unsignedlong
biHeigh
26
unsignedint
biPlane
28
unsignedint
biBitCoun
30
unsignedlong
biCompression
34
unsignedlong
biSizeImage
38
unsignedlong
biXPelsPerMeter
42
unsignedlong
biYPelsPerMeter
46
unsignedlong
biClrUsed
50
unsignedlong
biClrImportant
biSize:
代表BITMAPINFOHEADER数据结构的大小,这项值固定为40。
biWidth:
图像行(水平方向)的点数。
biHeight:
图像列(垂直方向)的点数。
biPlane:
图像平面数,这个值固定为1。
biBitCount:
以几个Bits存储图像的一点,这项值只有可能是1,4,8或24。
biCompression:
压缩类型,这个值可能是0,1,或2。
0表示文件内的图像数据未曾压缩。
1或2表示图像数据已经压缩处理过。
1是代表所压缩的图像数据是256色,2代表所压缩的图像数据是16色。
因为BMP图像文件在压缩16色或256色图像数据时,所采用的压缩方法有些差异,所以必须用1或2分别表示256或16色图像数据。
至于单色和全彩色的图像数据,在BMP文件中一律不压缩处理,这是BMP图像文件非常特殊的一点。
biSizeImage:
压缩图像的大小,表示压缩的BMP图像文件内的图像数据占用了多少字节。
(例如,一个BMP图像文件中若存有320200的256色图像,且图像数据没有经过压缩处理,则biSizeImage=64000字节。
)
biXPelsPerMeter:
代表水平方向的分辨率,每米包含多少点。
biYPelsPerMeter:
代表垂直方向的分辨率,每米包含多少点。
biClrUsed:
指出图像使用了几种颜色。
例如,在16色模式下,这项值若为12,便表示本图像一共用了12种颜色。
如果值设为0,则代表所有16种颜色都被采用。
biClrImportant:
指出有几种颜色在图像中是重要颜色。
值若设为0,即表示所有可用颜色都是重要颜色。
(b)调色板数据
Windows将BMP图像文件的调色板数据结构,命名为RGBQUAD(见表3)
表3调色板数据结构
数据地址
数据类型
数据名称
0
unsignedchar
rgbBlue
1
unsignedchar
rgbGreen
2
unsignedchar
rgbRed
3
unsignedchar
rgbReserved
RGBQUAD
存放调色板数据。
请注意此处调色板数据的排列顺序——蓝、绿、红,与一般图像文件的颜色数据排列顺序正好相反。
调色板数据结构内,还多了一个保留值rgbReserved,没有任何意义,应将它设定为0。
调色板结构的大小为4*N,其中N的取值如下:
当biBitCount=1、4、8(且biClrUsed==0)时,N=2,16,256;
若biClrUsed!
=0,则N=biClrUsed。
在BMP文件中,即使是单色的BMP图像文件,也必须存放调色板数据,第一组的三原色代表背景颜色,第二组的三原色则代表前景颜色。
三、实验前准备
1.预习本实验中关于BMP图像文件的基本格式;
2.了解本实验的目的和实验内容。
四、实验内容
1.根据BMP图像文件的基本格式,利用BC编写8bits无压缩BMP图像文件的打开和存储的程序;
2.用所编程序对给定图像进行读写操作,并用Photoshop验证所编程序的正确性;
五、实验报告要求
1.总结对8bits无压缩BMP图像文件的读写操作过程;
2.总结用Photoshop验证所编写程序的过程。
3.对实验结果进行分析。
六、参考步骤和程序
打开VC程序——文件——新建——工程中的MFCAppWizard(exe),在工程下面的框中输入工程名(假定工程名为111),点确定——选多重文档,点下一个——后面都点下一个直到完成确定,基本框架就完成了,下面就加代码。
这时VC界面上左边框的下面有三个按钮:
ClassView、ResourceView和FileView,ClassView里面是工程111的类:
CAdoutDlg、CChildFrame、CMy111App、CMy111Doc、CMy111View和Globals;点ResourceView里面是资源类:
Accelerator、Dialog、Icon、Menu、StringTable、Toolbar和Version;点开FileView里面是文件类:
SourceFile、HeaderFiles、ResourceFiles和ReadMe.txt。
点界面的“工程”按钮——添加工程——新建——选C++SourceFile,在文件下面的框里输入文件名(如DIBAPI),点“结束”,这样在FileView中的SourceFiles里面就多了一个DIBAPI.cpp文件,所有的代码都加在该文件中。
再点界面的“工程”按钮——添加工程——新建——选C/C++HeaderFile,在文件下面的框里输入文件名(和前面的文件名必须一致),点“结束”,这样在FileView中的HeaderFiles里面就多了一个DIBAPI.h文件,该文件是DIBAPI.cpp的头文件。
点开DIBAPI.h文件,里面是空白的,把如下代码考入文件中:
//DIBAPI.h
#ifndef_INC_DIBAPI
#define_INC_DIBAPI
DECLARE_HANDLE(HDIB);
#definePALVERSION0x300
#defineIS_WIN30_DIB(lpbi)((*(LPDWORD)(lpbi))==sizeof(BITMAPINFOHEADER))
#defineRECTWIDTH(lpRect)((lpRect)->right-(lpRect)->left)
#defineRECTHEIGHT(lpRect)((lpRect)->bottom-(lpRect)->top)
#defineWIDTHBYTES(bits)(((bits)+31)/32*4)
#defineDIB_HEADER_MARKER((WORD)('M'<<8)|'B')
BOOLWINAPIPaintDIB(HDC,LPRECT,HDIB,LPRECT,CPalette*pPal);
BOOLWINAPICreateDIBPalette(HDIBhDIB,CPalette*cPal);
LPSTRWINAPIFindDIBBits(LPSTRlpbi);
DWORDWINAPIDIBWidth(LPSTRlpDIB);
DWORDWINAPIDIBHeight(LPSTRlpDIB);
WORDWINAPIPaletteSize(LPSTRlpbi);
WORDWINAPIDIBNumColors(LPSTRlpbi);
HGLOBALWINAPICopyHandle(HGLOBALh);
BOOLWINAPISaveDIB(HDIBhDib,CFile&file);
HDIBWINAPIReadDIBFile(CFile&file);
//在此处输入自己的函数声明
#endif//!
_INC_DIBAPI
上面这些函数是实现图像的读取、存储等图像处理的基本功能的,你将自己需要的函数也输入到“//在此处输入自己的函数声明”的下面。
点开DIBAPI.cpp文件,里面是空白的,将如下代码加入其中:
//DIBAPI.cpp
#include"stdafx.h"
#include"DIBAPI.h"
WORDWINAPIDIBNumColors(LPSTRlpbi)
{
WORDwBitCount;
if(IS_WIN30_DIB(lpbi))
{
DWORDdwClrUsed;
dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if(dwClrUsed)
return(WORD)dwClrUsed;
}
if(IS_WIN30_DIB(lpbi))
wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
else
wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
switch(wBitCount)
{
case1:
return2;
case4:
return16;
case8:
return256;
default:
return0;
}
}
WORDWINAPIPaletteSize(LPSTRlpbi)
{
if(IS_WIN30_DIB(lpbi))
return(WORD)(DIBNumColors(lpbi)*sizeof(RGBQUAD));
else
return(WORD)(DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
}
LPSTRWINAPIFindDIBBits(LPSTRlpbi)
{
return(lpbi+*(LPDWORD)lpbi+:
:
PaletteSize(lpbi));
}
DWORDWINAPIDIBWidth(LPSTRlpDIB)
{
LPBITMAPINFOHEADERlpbmi;
LPBITMAPCOREHEADERlpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
returnlpbmi->biWidth;
else
return(DWORD)lpbmc->bcWidth;
}
DWORDWINAPIDIBHeight(LPSTRlpDIB)
{
LPBITMAPINFOHEADERlpbmi;
LPBITMAPCOREHEADERlpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
returnlpbmi->biHeight;
else
return(DWORD)lpbmc->bcHeight;
}
BOOLWINAPIPaintDIB(HDChDC,LPRECTlpDCRect,HDIBhDIB,LPRECTlpDIBRect,CPalette*pPal)
{
LPSTRlpDIBHdr;
LPSTRlpDIBBits;
BOOLbSuccess=FALSE;
HPALETTEhPal=NULL;
HPALETTEhOldPal=NULL;
if(hDIB==NULL)
returnFALSE;
lpDIBHdr=(LPSTR):
:
GlobalLock((HGLOBAL)hDIB);
lpDIBBits=FindDIBBits(lpDIBHdr);
if(pPal!
=NULL)
{
hPal=(HPALETTE)pPal->m_hObject;
hOldPal=:
:
SelectPalette(hDC,hPal,TRUE);
}
:
:
SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
{
bSuccess=:
:
SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->left,\
(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),0,(WORD)DIBHeight(lpDIBHdr),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
}
else
{
bSuccess=:
:
StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->left,\
lpDIBRect->top,RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
}
:
:
GlobalUnlock((HGLOBAL)hDIB);
if(hOldPal)
:
:
SelectPalette(hDC,hOldPal,TRUE);
GlobalUnlock(hDIB);
returnbSuccess;
}
BOOLWINAPICreateDIBPalette(HDIBhDIB,CPalette*pPal)
{
LPLOGPALETTElpPal;
HANDLEhLogPal;
HPALETTEhPal=NULL;
LPSTRlpbi;
LPBITMAPINFOlpbmi;
LPBITMAPCOREINFOlpbmc;
BOOLbWinStyleDIB;
inti;
WORDwNumColors;
BOOLbResult=FALSE;
if(hDIB==NULL)
returnFALSE;
lpbi=(LPSTR):
:
GlobalLock((HGLOBAL)hDIB);
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
wNumColors=DIBNumColors(lpbi);
bWinStyleDIB=IS_WIN30_DIB(lpbi);
if(wNumColors!
=0)
{
hLogPal=:
:
GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(hLogPal==0)
{
:
:
GlobalUnlock((HGLOBAL)hDIB);
returnFALSE;
}
lpPal=(LPLOGPALETTE):
:
GlobalLock(hLogPal);
lpPal->palVersion=PALVERSION;
lpPal->palNumEntries=(WORD)wNumColors;
bWinStyleDIB=IS_WIN30_DIB(lpbi);
for(i=0;i<(int)wNumColors;i++)
{
if(bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags=0;
}
else
{
lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags=0;
}
}
bResult=pPal->CreatePalette(lpPal);
:
:
GlobalUnlock((HGLOBAL)hLogPal);
:
:
GlobalFree((HGLOBAL)hLogPal);
}
:
:
GlobalUnlock((HGLOBAL)hDIB);
returnbResult;
}
HGLOBALWINAPICopyHandle(HGLOBALh)
{
if(h==NULL)
returnNULL;
DWORDdwLen=:
:
GlobalSize((HGLOBAL)h);
HGLOBALhCopy=:
:
GlobalAlloc(GHND,dwLen);
if(hCopy!
=NULL)
{
void*lpCopy=:
:
GlobalLock((HGLOBAL)hCopy);
void*lp=:
:
GlobalLock((HGLOBAL)h);
memcpy(lpCopy,lp,dwLen);
:
:
GlobalUnlock(hCopy);
:
:
GlobalUnlock(h);
}
returnhCopy;
}
BOOLWINAPISaveDIB(HDIBhDib,CFile&file)
{
BITMAPFILEHEADERbmfHdr;
LPBITMAPINFOHEADERlpBI;
DWORDdwDIBSize;
if(!
hDib)
returnFALSE;
lpBI=(LPBITMAPINFOHEADER):
:
GlobalLock((HGLOBAL)hDib);
if(lpBI==NULL)
returnFALSE;
if(!
IS_WIN30_DIB(lpBI))
{
:
:
GlobalUnlock((HGLOBAL)hDib);
returnFALSE;
}
bmfHdr.bfType=DIB_HEADER_MARKER;
dwDIBSize=*(LPDWORD)lpBI+:
:
PaletteSize((LPSTR)lpBI);
if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
dwDIBSize+=lpBI->biSizeImage;
else
{
DWORDdwBmBitsSize;
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;
dwDIBSize+=dwBmBitsSize;
lpBI->biSizeImage=dwBmBitsSize;
}
bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize+:
:
PaletteSize((LPSTR)lpBI)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 数字图像 输入输出 显示