讲解BMP格式图片的解码方法

[复制链接]
5305 1

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
对BMP格式的解码是更加BMP图片的编码来进行的。现在根据编码格式来一步步分析并写出代码。
先用WINHEX软件打开一张分辨率为320×240的BMP格式图片:

第一步:判断是否为BMP格式图片
根据BMP格式的编码信息可以得到,只要是BMP格式的图片,前两个字节就是'B'和'M'。大家可以看编码信息,第一个字节和第二个字节就是B和M的ASCii码。

第二步:得出图像数据的起始位置相对于文件开头的偏移量
这一步的目的是什么呢,就是确定真正的图像数据是从第几个字节开始的。
在BMP格式编码信息的前14个字节里就有偏移量这个信息,那么到底是那几个字节是偏移量的信息呢。现在看看编码格式:
BMP的文件信息: 文件开头的14个字节
WORD BMPId;BMP文件标志,其值固定为0x4d42,即“BM”(两个字节)
DWORD FileSize;BMP文件大小,以字节为单位 (4个字节)
WORD Reserved1;BMP文件保留字,必须为0 (两个字节)
WORD Reserved2;BMP文件保留字,必须为0 (两个字节)
DWORD ImageOffset;图像数据的起始位置相对于文件开头的偏移量 (4个字节)
偏移量的信息是在这14个字节数据中的最后4个。那么如何计算出偏移量呢!
首先定义一个32位的数据 unsigned long int ImageOffset;和unsigned char Table[54];
数组用来装单片机读出的BMP图片的前54个字节数据。
ImageOffset = Table[13];
ImageOffset <<= 8;
ImageOffset |= Table[12];
ImageOffset <<= 8;
ImageOffset |= Table[11];
ImageOffset <<= 8;
ImageOffset |= Table[10];
最终就得出了偏移量ImageOffset.

第三步:得出BMP格式图片是多少位和图片的像素
在上面的14个字节后还有40个字节的信息可以给我们分析。我们只需要分析出我们需要的信息。现在看下面的信息有哪些:
Bmpinfoheader 文件信息之后的40个字节
DWORD HeaderSize;BMP图像信息大小(40或12),以字节为单位 (4个字节)
DWORD ImageWidth;BMP图像宽度,以像素为单位 (4个字节)
DWORD ImageHeight;BMP图像高度,以像素为单位 (4个字节)
WORD EquipLevel;目标设备的级别(色彩平面数),固定为1 (2个字节)
WORD BitsPerPixel;每个像素所需要的位数,1,4,8,24 (2个字节)
DWORD EncodeType; 压缩类型,0(不压缩),1(BI_RLE8),2(BI_RLE4) (4个字节)
DWORD ImageSize; BMP位图大小,以字节为单位 (4个字节)
DWORD XPixelPerMeter设备水平分辨率(每米像素数) (4个字节)
DWORD YPixelPerMeter设备垂直分辨率(每米像素数) (4个字节)
DWORD ColorUsed实际使用色彩数目,若为0,则由位数定 (4个字节)
DWORD ColorImportant图像中重要的色彩数目。为0,表示调色板内所有的颜色都是重要的 (4个字节)

定义四个数据:unsigned long int ImageWidth,ImageHeight,ImageSize;
unsigned char BitsPerPixel;
ImageWidth = Table[21];
ImageWidth <<= 8;
ImageWidth |= Table[20];
ImageWidth <<= 8;
ImageWidth |= Table[19];
ImageWidth <<= 8;
ImageWidth |= Table[18]; //计算出了像素的宽
ImageHeight = Table[25];
ImageHeight <<= 8;
ImageHeight |= Table[24];
ImageHeight <<= 8;
ImageHeight |= Table[23];
ImageHeight <<= 8;
ImageHeight |= Table[22]; //计算出像素的高
BitsPerPixel = Table[28]; //读出每个像素点需要多少位。就是图片是多少位的
ImageSize = ImageHeight * ImageWidth * BitsPerPixel; //计算出BMP位图的大小

第四步:根据不同的位图来用不同的函数求出彩屏需要的RGB显示值
我们知道的偏移量,那么真正要显示的数据就是,从偏移量那里开始后面的字节就是我们图片的显示数据。显示数据的大小就是我们上面所求的BMP位图大小。彩屏液晶上面的每个像素点都是一个16位的数据,这16位的数据包含了该点的RGB的值。那么我们怎么根据图片里的数据来求出RGB的值并转化为一个16位的数据呢!
首先说32位的BMP图片:
32位的图片是一个像素点的信息由4个字节表示。
BYTE rgbBlue; (B)
BYTE rgbGreen; (G)
BYTE rgbRed; (R)
BYTE rgbReserved 为0;(不用管)
现在我们就把这几个数据转换为给彩屏显示的16位的数据。这四个数据如果存在RGB[4]这个数组里。
对于彩屏的16位数据是:R(5位)G(6位)B(5位);
Blue = RGB[0] * 31 / 255;
Green = (RGB[1] * 63 / 255) << 5;
Red = (RGB[2] * 31 / 255) << 11;
RGB_TFT = Blue + Green + Red; //给彩屏的16位数据
RGB[3]忽略不管。
再说24位的BMP图片:
24位的图片是一个像素点的信息由3个字节表示。
BYTE rgbBlue; (B)
BYTE rgbGreen; (G)
BYTE rgbRed; (R)
剩下的和上面处理是一样的,不同的是这里的数组定义为RGB[3];
再说16位的BMP图片:
16位的每个像素点由两个字节表示。在写彩屏函数的时候就会写到一个函数就是向一个像素点写两个8位的数据。所以这里就不用多讲,就是把数组定义位RGB[2],然后将这数组里的两个8位数据写入彩屏就好了。


qqaa2019.png

举报

回复

1 个评论

latter  新手上路  发表于 2014-5-10 10:50:03  | 显示全部楼层
bucuoooooo
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

图文热点

更多

社区学堂

  • Ameya360邀请您参加2017 ROHM科技展Ameya360邀请您参加2017 ROHM科技展 尊敬的客户: 您好!感谢您一直以来对罗姆的支持与厚爱! 罗姆将于2017年11月
  • 智能家居生态论(上)智能家居生态论(上) 从问题开始? 让我们从一个问题开始!学会提问是成长的开始, 受两“罗”的《长谈
  • 好书推荐好书推荐 LABVIEW宝典(第2版)简版电子书出炉了,需要赶紧下 此书你不得不读的几个理由:
更多

客服中心

QQ:187196467 服务时间:周一至周日 8:30-20:30

关注我们

快速回复 返回列表 客服中心 搜索 官方QQ群
关于我们
关于我们
友情链接
联系我们
帮助中心
网友中心
购买须知
支付方式
服务支持
资源下载
售后服务
定制流程
关注我们
官方微博
官方空间
官方微信
快速回复 返回顶部 返回列表