你所能用到的BMP格式介绍(二)_第1页
你所能用到的BMP格式介绍(二)_第2页
你所能用到的BMP格式介绍(二)_第3页
你所能用到的BMP格式介绍(二)_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一 可能你忽视的基础 在正式开始之前 我不得不从最基本的地方开始 因为这些地方大多数人会忽视的一干二净 如果 不在开始进行说明 那么在后面一定会有很多困惑的地方 最开始我们回到数字在计算机里的表示 回到最开始的问题上 2 4 for int i 0 i0 7 if int unsigned char str i 0 x10 8 9 cout 0 10 11 cout hex int unsigned char str i 12 13 14 int num 10 15 total str str unsigned char num 16 17 cout endl 代码虽然很少看上去比程序还混乱 我会一行一行解释的 首先第一行一行一行的读取文件中的数 值 有没有思考过 文件流读 bmp 中怎么样算是一 行 这问题下面再进行说明 但是可以明确告诉你的 是 bmp 中绝对不是按一个像素行为一行的 接下来是取得读入字符串的长度 再接下来进入循环 循环的一开始的一个判断是为了做每行显示 16 个字符的 可以不用管它 然后下面的这些看似简单的包含了这个程序的核心部分 让我们回到字节 0 1 42 4d 这上面来 按照程序我们读入这个第一个字节 str 0 储存的是 B 这 个字符 也是 42 这个值 至于为什么是 42 参见 ASCII 码表 按照我 们第一部分说的 对于一字节的数我们应该用 unsigned char 来表示 所以我们进行了将 str i 的值转 换成 unsigned char 至于再转换成 int 是为了能够显示出十六进制的数字 一个让人疑惑的地方出现了 循环内为什么要有最后两句 这要回到 getline 这个函数的原理上面 了 前面说过 getline 是读取文件的一行 那么怎样判断文件的一行呢 我们来看一下 getline 的定义 After the function extracts an element that compares equal to delim in which case the element is neither put back nor appended to the controlledsequence msdn 上写的是如果读到一个终止符 那么这个函数结束并且这个终止符不会加到这个字符串中 哪 些字符是终止符呢 一般来说换行 0 x0A 和回车 0 x0D 都会被选为终止符 括号是他们的 ASCII 码 如此便得到了一个图像文件的全部数据 在我们的程序中是存储在 total str 之中的 这里面包括了 文件信息头 位图信息头 调色板 当然如果有的话 位图数据区 下面需要进行的就是依次取出每个 信息 然后保存起来 按照前面的字节顺序 注意小端法或者大段法 这里我想提到的一个问题就是 为什么在第一部分说了一下看似没有关系进制转换问题呢 如果你在 存储各个位图部分的数据的时候 如果发现输出的数据不对 请你返回去仔细阅读一下第一部分以及回忆 下基本数据的长度 三 把数据存储组织起来 下面说明怎么将上面取出的数据字符串按照 bmp 的四部分存储起来 存储的目的一个是为了标示 还有一个作用就是在读取的时候方面取出来 首先 bmp 最先的一个部分是文件信息头 我们定义一个结构如下 在开始下面介绍的内容之前 先要说明一下这些 UINT16 以及 DWORD 的数据类型 在 32 位计算机中 short 由两个字节表示的 int 是四字节表示的 所以 UINT16 WORD 表示的 是两个字节 DWORD LONG 都表示四字节数 结构中各个字段的意思如注释所示 和前面说明的文件信息头的字段是一一对应的 下面来展示怎么样将 读出来的字符串 total str 赋值到某一个字段上 根据我们读取的字符串 total str 0 和 total str 1 分别是字符 b 和 m 这是两个字节 那么我 们需要将 BITMAPFILEHEADER 里面的 bfType 赋值为这两个值 采用的赋值方法如下所示 是不常见的左移操作 这样的话方便的就能将两个一字节的数扩展为双字节的数 这样 bh bfType 里面存的值就是 0 x424d 你可以输出来进行验证 这个看起来不起眼的操作似乎很容易扩展成将四个四字节的数扩展为一个四字节的数 但是当你 操作的时候就会发现并不是这样 如果你是这样操作的话 那么你可以做一下输出 你会发现结果出乎你意料的错误 为什么 在第 一部分我提过的符号扩展 后面所有的都没有进行过类型转换 total str i 进行移位并且或操作默认的 是带符号操作的 举个例子 如果 total str 5 2 依次是 00 00 00 f3 那么你这样做之后 bh bfSize 就 会变成 ff ff ff f3 虽然 bh bfSize 是无符号数 但是右边的是有符号数 所以你得到的一定是错误的结果 那正确的做法应该是怎么样的 一种做法如下 至于为什么这样是对的 我在这里不进行说明了 按照上面的方法 依次对文件信息头内的字段赋值 一样的对其他三个部分进行赋值 位图信息头结构 数据区结构 调色板结构 也许 你会问我 数据区和调色板为什么不用 unsigned char 这里完全可以用 unsigned char 我用 UINT16 的目的是因为我懒得再重新定义一个数据类型了 赋值的时候要注意的我在上面说过了 其他的要注意的我想说的就是不要忘记有数据对齐 如果你 忘了 请你回去再看一下前面的说明 当你能够把 bmp 的每一部分保存下来之后 那么你就可以对 bmp 做各种操作了 从另一种角度来说 你可以自己构造自己的 bmp 位图 四 如果你会 MFC 如果你熟悉 windows 编程 那么你一定知道上面的结构在 MFC 以及 windows 编程里都是已经有 了的结构 那你需要做的只是将图片加载到内存 在控件上显示 如果你想学这一部分的 MFC 构成 那么搜索的关键词是 MFC GDI 在进行这个部分的 MFC 编程 时 但是 MFC 的位图编程这一块所提供的类 CBitmap 并不好用 包括 CPalett

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论