在应用程序类的InitInstance函数中,有这么两句:
// 分析标准外壳命令、DDE、打开文件操作的命令行
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
//添加下面这句话,即可
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
后续待添加:)
多媒体编程
实验一 报告 2008212519_王俊华
实验过程
分析bmp文件格式
,格式见附录一
以最精简最实用的结构定义CBmp类,将作业中所需的操作封装到该类
实现文档/视图结构
在实验中记录遇到的问题
程序框架
文档/视图结构
CBmp类封装了对Bmp文件的读操作和显示,以及将当前取得的RGB值转化为亮度值
详细结构如图一
图一
CBmpViewerDoc 中添加
CBmp *bmp 成员,作为载入的位图对象存储,实现如下两个成员函数:
菜单
作业->信息头分析
OnToText(); //解析bmp文件头信息,并写入文本
菜单
作业->RGB转成YUV
OnToYUV(); //按bmp图片像素阵列输出亮度值到文本
CBmpViewerview
中修改OnDraw()
函数,以显示bmp图片;
CBmpViewerview
中修改OnInitialUpdate()
函数,以实现滚屏视图;
软件操作方法
显示
通过文件->打开
bmp图片即可
读取头文件
菜单 作业->信息头分析
然后在打开的文件夹里
选择合适的txt文本
或者直接新建
按bmp图片像素阵列输出亮度值到文本
菜单 作业->RGB转成YUV
实验中遇到的问题及相关解决方法
CString的格式化输出
%c 单个字符
%d 十进制整数
%f 十进制浮点数
%o 八进制数
%s 字符串
%u 无符号十进制数
%x 十六进制数
%% 输出百分号%
一个格式说明可以带有几个修饰符,用来指定显示宽度,小数尾数及左对齐等:
- 左对齐
+ 在一个带符号数前加'+'或'-'号
域宽用前导零来填充,而不是用空白符
域宽是一个整数,设置了打印一个格式化字符串的最小域。精度使用小数点后加数字表示的,给出每个转换说明符所要输出的字符个数。
注意:带修饰符的显示可能不正常。
数据格式说明由“%”开头,形式为
%<数据输出宽度说明><格式符>,数据格式说明用在需要输出变量或运算数值结果的时候,它的个数与输出表列的个数一一对应。
数据宽度说明中如果实际数据小于宽度,则根据宽度是否大于零而左补空格或右补空格。如果实际数据大于宽度,按实际位数输出。如果缺省宽度说明,则按实际宽度输出。
CString.format('%10f',
a);
10表示把a以10个字符宽度格式化
%f形式输出,则小数部分为6位;
例
%10f
若a的整数部分位数+小数点(1位)+小数部分位数大于等于10,则按实际a的形式格式化;
若a的整数部分位数+小数点(1位)+小数部分位数小于10,则在前面补空格,补足10位;
例
%.7f 则
a的小数部分位数若大于7,则截取7位小数,整数部分不变;
a的小数部分位数若小于等于7,则不满7位的部分后面以0补足;
str.Format(_T('Left-justified
integer: %.6d\n'), b);
%.6d
若整数b不满6位则在最高为前面补0;
若整数b大于等于6位则形式不变;
%6d
若整数b不满6位,则在最高位前面补上空格,是之格式化为6个字符宽度;
若整数b大于等于6位则形式不变。
CFile 遇到的文件读写错误和指针定位
CFile定义的文件,在读写操作结束的时候一定要close(),否则会造成文件共享错误;
文件读写是从类型或者结构的末端开始的。
CFile->Read()
读取文件结束后,指针就停留在结构末端,下一次读取的时候不用调用seek
重新定位文件指针。
指针转换的学习
ptrHeader
= (BITMAPFILEHEADER*) bmPtr;
ptrInfo
= (BITMAPINFO*) &bmPtr[sizeof(BITMAPFILEHEADER)];
ptrBits
= &bmPtr[ptrHeader->bfOffBits];
指针可以根据结构的长度
自动截断原指针所指向结构的长度
可以方便的把某个指针的一部分快速的赋给另一个指针
Dib位图显示
int
StretchDIBits(
HDC
hdc, // handle to DC
int
XDest, // x-coord of destination upper-left corner
int
YDest, // y-coord of destination upper-left corner
int
nDestWidth, // width of destination rectangle
int
nDestHeight, // height of destination rectangle
int
XSrc, // x-coord of source upper-left corner
int
YSrc, // y-coord of source upper-left corner
int
nSrcWidth, // width of source rectangle
int
nSrcHeight, // height of source rectangle
CONST
VOID *lpBits, // bitmap bits
CONST
BITMAPINFO *lpBitsInfo, // bitmap data
UINT
iUsage, // usage options
DWORD
dwRop // raster operation code
);
int
SetDIBitsToDevice(
HDC
hdc, // handle to DC
int
XDest, // x-coord of destination upper-left corner
int
YDest, // y-coord of destination upper-left corner
DWORD
dwWidth, // source rectangle width
DWORD
dwHeight, // source rectangle height
int
XSrc, // x-coord of source lower-left corner
int
YSrc, // y-coord of source lower-left corner
UINT
uStartScan, // first scan line in array
UINT
cScanLines, // number of scan lines
CONST
VOID *lpvBits, // array of DIB bits
CONST
BITMAPINFO *lpbmi, // bitmap information
UINT
fuColorUse // RGB or palette indexes
);
调色板的创建
调色板的存在到底有什么用处,还不是很清楚,只是猜测可能每次在dc上画图,用逻辑调色板修改系统调色板,可以将系统调色板缺少的颜色都补上,使得图片显色的时候保真。
调色板是通过logPalette创建的。把代码贴在这里,以防遗忘……
附录一
位图文件分为四部分:
(1)位图文件头BITMAPFILEHEADER
位图文件头BITMAPFILEHEADER是一个结构体,长度为14字节,定义为:
typedef struct
tagBITMAPFILEHEADER
{
WORD
bfType; //文件类型,必须是0x424D,即字符串"BM"
DWORD
bfSize; //文件大小,包括BITMAPFILEHEADER的14个字节
WORD
bfReserved1; //保留字
WORD
bfReserved2; //保留字
DWORD
bfOffBits; //从文件头到实际的位图数据的偏移字节数
} BITMAPFILEHEADER;
(2)位图信息头BITMAPINFOHEADER
位图信息头BITMAPINFOHEADER也是一个结构体,长度为40字节,定义为:
typedef struct
tagBITMAPINFOHEADER
{
DWORD
biSize; //本结构的长度,为40
LONG
biWidth; //图象的宽度,单位是象素
LONG
biHeight; //图象的高度,单位是象素
WORD
biPlanes; //必须是1
WORD
biBitCount;
//表示颜色时要用到的位数,1(单色),
4(16色),
8(256色),
24(真彩色)
DWORD
biCompression;
//指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS等,BI_RGB表示不压缩
DWORD
biSizeImage;
//实际的位图数据占用的字节数,即
biSizeImage=biWidth’ ×
biHeight,biWidth’是biWidth
按照4的整倍数调整后的结果
LONG
biXPelsPerMeter; //目标设备的水平分辨率,单位是每米的象素个数
LONG
biYPelsPerMeter; //目标设备的垂直分辨率,单位是每米的象素个数
DWORD
biClrUsed; //位图实际用到的颜色数,0表示颜色数为2biBitCount
DWORD
biClrImportant; //位图中重要的颜色数,0表示所有颜色都重要
} BITMAPINFOHEADER;
(3)调色板Palette
调色板Palette针对的是需要调色板的位图,即单色、16色和256色位图。对于不以调色板方式存储的位图,则无此项信息。调色板是一个数组,共有biClrUsed个元素(如果该值为0,则有2biBitCount个元素)。数组中每个元素是一个RGBQUAD结构体,长度为4个字节,定义为:
typedef struct
tagRGBQUAD
{
BYTE
rgbBlue; //蓝色分量
BYTE
rgbGreen; //绿色分量
BYTE
rgbRed; //红色分量
BYTE
rgbReserved; //保留值
} RGBQUAD;
(4)实际的位图数据ImageDate
对于用到调色板的位图,实际的图象数据ImageDate为该象素的颜色在调色板中的索引值;对于真彩色图,图象数据则为实际的R、G、B值:
a.单色位图:用1bit就可以表示象素的颜色索引值;
b.16色位图:用4bit可以表示象素的颜色索引值;
c.
256色位图:1个字节表示1个象素的颜色索引值;
d.真彩色:3个字节表示1个象素的颜色R,G,B值。
此外,位图数据每一行的字节数必须为4的整倍数,如果不是,则需要补齐。奇怪的是,位图文件中的数据是从下到上(而不是从上到下)、从左到右方式存储的。
详细位移结构见表01
表01
位图文件结构内容摘要
| 偏移量 | 域的名称 | 大小 | 内容 |
| 0000h | 文件标识 | 2 |
|
| 0002h | File | 1 | 用字节表示的整个文件的大小 |
| 0006h | Reserved | 1 | 保留,必须设置为0 |
| 000Ah | Bitmap | 1 | 从文件开始到位图数据开始之间的数据(bitmap |
| 000Eh | Bitmap | 1 |
|
| 0012h | Width | 1 | 位图的宽度,以象素为单位 |
| 0016h | Height | 1 | 位图的高度,以象素为单位 |
| 001Ah | Planes | 1 | 位图的位面数(注:该值将总是1) |
| 001Ch | Bits | 1 |
|
| 001Eh | Compression | 1 |
|
| 0022h | Bitmap | 1 | 用字节数表示的位图数据的大小。该数必须是4的倍数 |
| 0026h | HResolution | 1 | 用象素/米表示的水平分辨率 |
| 002Ah | VResolution | 1 | 用象素/米表示的垂直分辨率 |
| 002Eh | Colors | 1 | 位图使用的颜色数。如8-比特/象素表示为100h或者 |
| 0032h | Important | 1 | 指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要 |
调色板数据 | 根据BMP版本的不同而不同 | Palette | N |
|
图象数据 | 根据BMP版本及调色板尺寸的不同而不同 | Bitmap | xxx | 该域的大小取决于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。 |
~
1
~
Copyright 2008. All right reserved. Theme Design by Good Design Web
© 2008 南辕北辙 沧海桑田 Bloggerized by Falcon Hive.com