参考文献
[1]vscode查看16进制格式可用插件Hex Editer[教程]
[2]BMP图片格式介绍链接
前言
本次问题是在zynq进行SD卡读写的使用碰到的。情形如下:zynq的PS端从SD卡读bmp图片再写入到SD卡中。在读取bmp图片的头文件的时候发现数据不对,后来发现直接改文件后缀名不能改变头文件,需要进行其他格式转换才可以。检查了半天代码,最后检查文件头格式和数据才发现是图片转换的问题——泪目。
BMP转换
下面用直接改后缀名、convertio、python来转和直接另存,这四种方法虽然转换后在电脑中显示一样,但是16进制文件均不一样,下面来看下四种方法的区别。通过vscode查看16进制格式。
原来jpeg图片
方法一后缀名更改
方法二convertio转换后
方法三python利用PIL库转换
方法四直接另存为bmp图片
BMP转换结果以及分析
由上面三种方法可以看到bmp的文件头均不一样,那哪个是对的呢?根据byte2~byte5可以计算出文件的长度(计算方法),640x480的24位bmp图片文件长度应该为 640 ∗ 480 ∗ 3 + 54 = 921654 b y t e s 640 * 480 * 3 + 54 = 921654 bytes 640∗480∗3+54=921654bytes
下面是各方法保存在SD卡的bmp图片。
方法一后缀名更改
首先排除方法一,方法一和原jpeg图片编码一样直接排除。由于bmp文件前两byte表示的是文件格式且bmp的文件格式为0x424d,直接改后缀名前两byte为0xffd8,可见后面保存在SD卡的图片也是完全错的。
方法二convertio转换后
方法二文件长度为 3 2 ′ h 000 e 108 a = 3 2 ′ d 921738 ! = 3 2 ′ d 921654 32'h000e108a = 32'd921738 != 32'd921654 32′h000e108a=32′d921738!=32′d921654,因此也排除方法二。可见后面保存在SD卡的图片也是错的,有一定的相差。
方法三python利用PIL库转换
方法三文件长度$32’h000e1036 = 32’d921654 $,初步判断python转换是正确的。后面保存在SD卡的图片是正确的。
以下是python的代码
from PIL import Image
# 打开图片
img = Image.open("1.jpeg")
# 将图片保存为BMP格式
img.save('output.bmp')
方法四直接另存为bmp图片
方法四直接windows自带的图片软件另存为的,本来以为应该没问题,但是出乎意料。方法四文件长度为 3 2 ′ h 0012 c 036 = 3 2 ′ d 1228854 ! = 3 2 ′ d 921654 32'h0012c036 = 32'd1228854 != 32'd921654 32′h0012c036=32′d1228854!=32′d921654,首先文件大小差很多,此外仔细观察数据存在很多0xFF,不难想到最后保持再SD卡的图片大概率是错误的。可见后面保存在SD卡的图片也是完全错的。
总结
综上所述,利用python进行转换是最靠谱的。那为什么各种方法转换成bmp图片结果得到不一样,但是在windows里面显示是正确的,但是写入到sd卡里就原形毕露了呢?由于这个不是目前重点,以找到bug为主,就不深究了。如果有大佬知道,恳请指教。