SD卡FAT32文件结构(2)---创建与写入BMP位图

下图为本人512MB诺基亚SD卡根目录的数据,

     1(红色处):卷标,也就是名称,我的SD卡名称为WHETA。

     2(蓝色处):文件名。

     3(紫色处):文件类型。    从蓝色与紫色处,可以看出我的根目录里就一个东西,一张名为TESTV12的BMP位图。

     4(褐色处(2个)): 这个是文件开始的簇,注意格式,按照图来,读取的数值为0x0000 0300,但真实表示的数值为0x0000 0003。也就是从第三簇开始的。

 

    然后,我们参照FAT表,找出BMP位图的所存储的位置,以及如何存储的。下图为我FAT1表,

     红色为簇1,绿色为簇2,蓝色为簇3。

     红色处可以理解为簇1,也可以理解为前8个字节表示为FAT32的表头。

     根据根目录的显示,我们所找的图片位于第3簇,也就是蓝色部分,蓝色处得值为0x04000 0000,也就是大端格式的0x0000 0004 这个数字表明,我们的数据开始与簇3,而且1个簇不够存,剩下的存储为簇4。簇4为紫色部分,其值为0xFFFF FF0F也就是完结标志。

      总体来时,也就是表示文件从3簇开始,存储了簇3与簇4两个簇。而簇4有几大的可能没有储存满。那么簇4剩下的部分不存储其他文件的数据。下图是上面图片的属性,

       图中两处红线,大小为5.67KB,占用空间为8KB。这是因为,每个簇有8个扇区(针对于我卡而言),而每个扇区512Byte,所以,每个簇为4KB,那么我们的BMP文件占用了2个簇,所以占用了8KB存储空间,而其实际大小为5.67KB。

     

       这个FAT32结构非常有效的解决了数据追加的问题,比如,我有两个TXT文件,分别为0.TXT和1.TXT。我首先创建了0.TXT,向里面写了2KB的数据,占用一个簇,假设为簇3。然后我由创建了一个1.TXT文件,同样为2KB数据,占用一个簇,假设为簇4。而现在我要向0.TXT写4KB数据,那么我们就可以先填满簇3,然后寻找一个空闲的簇,假设为簇5,那么只需要改写FAT表的结束标志,将其改为0x0500 0000(小端数据格式)。然后若数据不能填满簇5,则在FAT表中簇5的位置写结束标志0xFFFF FF0F,如果能填满簇5而且还有数据剩下,那么就再找看空闲的簇,直到数据完全存到SD卡内。

 

      那么,就TXT文件而言,是不需要文件头的,需要的是在根目录生成一个相关文件索引,然后指明文件开始的簇,然后把数据存储到相应的簇,然后存满一个簇就刷新一遍FAT表即可。

     

      但是,要生成其他文件就不能那么简单了,比如我希望创建一个BMP位图。那么,我就需要在数据开始前,写一个BMP文件头,当然这个文件头存储于数据的开始处。

    

      我的SD卡内,现在有一张全黑的图片,其文件头如下所示,

     

 

     其中,红色部分为BMP文件的文件头,占用了54个字节,其后面的00为数据(由于是纯黑的图片)。

     1.(红色划线处):定值,为0x424D,即BM。     

     2.(绿色划线处):位图的文件大小,注意,这里是位图的数据+位图的头文件的大小。

     3.(深绿划线处):必须为0,定值。

     4.(浅蓝划线处):表示了文件开始到数据开始的位移量。在上图,即表示地址0x000F D600到0x00F D636的位移量,结果为0x36。其小端数据为0x3600 0000。

     (注:严格的说,以上14字节的信息为文件头,接下来的40字节为位图信息)

     5.(深蓝划线处):表示图像信息描述块大小,也就是接下来的40字节的信息,所以值一般为0x28(转小端之后为0x2800 0000).

     6.(紫色划线处):图像宽度,这个就可以自己定义了。我定义的图像宽度为47,16进制小端数据为0x2F00 0000。

     7.(深紫划线处):图像高度,这个也是自己定义的。我定义为40,16进制小端数据为0x2800 0000。

     8.(蓝绿划线处):0x0100,小端数据,同样为定值。

     9.(樱色划线处):0x1800,小端数据,表示为24。也就是RGB图像,所以,图像上每个像素由三个字节表示。

                                可能值为1,二值化图像 ,图像上每8个像素由1个字节表示。

                                            4,16色图像    ,图像上每4个像素由1个字节表示。

                                            8, 256色图像 ,图像上每2个像素由1个字节表示。

                                          24,RGB图像     ,图像上每1个像素由3个字节表示。

  10.(紫色划线处):为0表示不压缩,为1表示8位压缩,为2表示4位压缩。

  11.(褐色划线处):图像数据区大小,就是不包含文件头,仅仅为数据区的大小。但是其一定要为4的倍数。

  后续数据就不用管了,全写0就OK了。

 

      这里值得一说的是,一个扫描行必须是4的倍数。拿我上面的图像来说,图像规格为47X40。那么一个扫描行为47*3 = 141个字节,但是141并不是4的倍数,与之最接近的4的倍数的数为144(只能加,不能减)。所以,一个到扫描行为144个字节,前141个字节为图片数据,之后的3个字节补0。

      那么,图片的数据大小,也就变成了   144(扫描行)*40(图片宽度) = 0x0000 1680,转化为小端,为0x8016 0000。将数据填入褐色划线处,那么位图文件的大小为 0x0000 1680(图片大小) + 0x0000 0036(文件头到数据区偏移量) =  0x16B6 0000。将这个信息填入2(绿色划线处)。

      之后再填写相关图片的每个扫描行的信息,即可。

 

      需要FAT32文件层的操作,如果是像我一样的新手,不推荐自己写,因为有许多东西是考虑不到的。简易下载成型的FAT32系统,比如国内比较著名的znFAT,之类的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值