OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6039|回复: 10

BMP图片解码程序有疑问大佬们求解答

[复制链接]

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
发表于 2022-3-7 10:16:49 | 显示全部楼层 |阅读模式
1金钱
代码
while(count<readlen)  //读取一簇1024扇区 (SectorsPerClust 每簇扇区数)
                    {
                                if(color_byte==3)   //24位颜色图
                                {
                                        switch (rgb)
                                        {
                                                case 0:                                  
                                                        color=bmpbuf[count]>>3; //B
                                                        break ;          
                                                case 1:          
                                                        color+=((u16)bmpbuf[count]<<3)&0X07E0;//G
                                                        break;          
                                                case 2 :
                                                        color+=((u16)bmpbuf[count]<<8)&0XF800;//R          
                                                        break ;                       
                                        }   
                                }else if(color_byte==2)  //16位颜色图
                                {
                                        switch(rgb)
                                        {
                                                case 0 :
                                                        if(biCompression==BI_RGB)//RGB:5,5,5
                                                        {
                                                                color=((u16)bmpbuf[count]&0X1F);                 //R
                                                                color+=(((u16)bmpbuf[count])&0XE0)<<1; //G
                                                        }else                //RGB:5,6,5
                                                        {
                                                                color=bmpbuf[count];                          //G,B
                                                        }  
                                                        break ;   
                                                case 1 :                                                    
                                                        if(biCompression==BI_RGB)//RGB:5,5,5
                                                        {
                                                                color+=(u16)bmpbuf[count]<<9;  //R,G
                                                        }else                  //RGB:5,6,5
                                                        {
                                                                color+=(u16)bmpbuf[count]<<8;        //R,G
                                                        }                                                                           
                                                        break ;         
                                        }                     
                                }else if(color_byte==4)//32位颜色图
                                {
                                        switch (rgb)
                                        {
                                                case 0:                                  
                                                        color=bmpbuf[count]>>3; //B
                                                        break ;          
                                                case 1:          
                                                        color+=((u16)bmpbuf[count]<<3)&0X07E0;//G
                                                        break;          
                                                case 2 :
                                                        color+=((u16)bmpbuf[count]<<8)&0XF800;//R          
                                                        break ;                       
                                                case 3 :
                                                        //alphabend=bmpbuf[count];//不读取  ALPHA通道
                                                        break ;                             
                                        }       
                                }else if(color_byte==1)//8位色,暂时不支持,需要用到颜色表.
                                {
                                }

这是我在文档里找到的内容:
biBitCount=16表示位图最多有 216 种颜色。每个色素用 16 位(2 个字节)表示。这种格式叫作高彩色,或叫增强型 16 位色,或 64K 色。它的情况比较复杂,当 biCompression 成员
值是 BI_RGB 时,它没有调色板。16 位中,最低的 5 位表示蓝色分量,中间的 5 位表示绿量,高的 5 位表示红色分量,一共占用了 15 位,最高的一位保留,设为 0。这种格式也被55516 位位图。

color_byte==2也就是16位颜色图那里,从逻辑上看是先把第一个字节读出来,低5位是蓝色(可注释为什么是R?是不是写错了?),剩下的高3位取出来左移1位是绿色的一部分(也就是6到8位,最低位是第0位),再读第二个字节,左移9位,就是最高位不要,之后高5位是红色,剩下的低两位与前面3位一起组成绿色。所以结果就是低5位是蓝色(0到4位),第5位为0,6到10位是绿色,11到15位是红色。这与文档说的不对啊,文档说了“最低的 5 位表示蓝色分量,中间的 5 位表示绿量,高的 5 位表示红色分量,一共占用了 15 位,最高的一位保留,设为 0。”为什么程序是第5位为0而不是最高位为0呢?
还有个疑问,第一次读第一个字节时是作为0到7位来处理的,第二次是作为8到15位来处理的,为什么不是反过来的?跟什么有关?

QQ浏览器截图20220307093042.png
QQ浏览器截图20220307093042.png

最佳答案

查看完整内容[请看2#楼]

电路上移位,以51单片机为例:P0口的0~6脚分别接P1口的1~7脚,P1.0接地,然后运行, P0=x; y=P1; 就相当于是y=x
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

3387

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8627
金钱
8627
注册时间
2020-5-11
在线时间
4059 小时
发表于 2022-3-7 10:16:50 | 显示全部楼层
laugh0 发表于 2022-3-7 18:02
大佬我试了下原来图片是这样的,改成G的最高位为0是这样的,颜色是有点不对。你的意思是说G的最低位补0还 ...

电路上移位,以51单片机为例:P0口的0~6脚分别接P1口的1~7脚,P1.0接地,然后运行,
P0=x;
y=P1;
就相当于是y=x<<1;
专治疑难杂症
回复

使用道具 举报

12

主题

3387

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8627
金钱
8627
注册时间
2020-5-11
在线时间
4059 小时
发表于 2022-3-7 10:33:07 | 显示全部楼层
本帖最后由 LcwSwust 于 2022-3-7 10:35 编辑

16位数据在内存中的存储方式:

电脑上估计是“小端”模式:低字节放前面,高字节放后面。
单片机上多数是“大端”模式:高字节放前面,低字节放后面。
专治疑难杂症
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-3-7 12:48:02 | 显示全部楼层
LcwSwust 发表于 2022-3-7 10:33
16位数据在内存中的存储方式:

电脑上估计是“小端”模式:低字节放前面,高字节放后面。

第一次读的是低地址数据,放到低字节,这是小端模式吧
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-3-7 13:02:42 | 显示全部楼层
laugh0 发表于 2022-3-7 12:48
第一次读的是低地址数据,放到低字节,这是小端模式吧

我验证了下,确实是小端。那第一个问题,第5位为0是为什么啊大佬们
回复

使用道具 举报

12

主题

3387

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8627
金钱
8627
注册时间
2020-5-11
在线时间
4059 小时
发表于 2022-3-7 14:23:03 | 显示全部楼层
本帖最后由 LcwSwust 于 2022-3-7 14:24 编辑
laugh0 发表于 2022-3-7 13:02
我验证了下,确实是小端。那第一个问题,第5位为0是为什么啊大佬们
关于RGB555 RGB565.你看下这个:
https://blog.csdn.net/byhook/article/details/84262330

专治疑难杂症
回复

使用道具 举报

12

主题

3387

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8627
金钱
8627
注册时间
2020-5-11
在线时间
4059 小时
发表于 2022-3-7 14:44:07 | 显示全部楼层
本帖最后由 LcwSwust 于 2022-3-7 14:47 编辑

由于TFT屏是RGB565格式的,所以将数据由RGB555格式转为RGB565格式时,G多了一位,所以将G的最低位补0。
傲游截图20220307144633.jpg
专治疑难杂症
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-3-7 16:52:42 | 显示全部楼层
大佬能不能是G的最高位补0?虽然可能麻烦点,还是必须是最低位补0?
回复

使用道具 举报

12

主题

3387

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8627
金钱
8627
注册时间
2020-5-11
在线时间
4059 小时
发表于 2022-3-7 17:08:57 | 显示全部楼层
laugh0 发表于 2022-3-7 16:52
大佬能不能是G的最高位补0?虽然可能麻烦点,还是必须是最低位补0?

这里的color数据可直接发送给TFT显示屏,若你把G弄成高位补0,那就得看显示屏是否能接受了,莫非发送给显示屏时还要再移位处理?你可以试一下显示白色图像看是否正常。

总之,最终是要看显示屏的。(也得看电路,若数据是高位补0,而电路上左移了一位,也是可以的,只是不符合一般人的习惯)
专治疑难杂症
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-3-7 18:02:24 | 显示全部楼层
LcwSwust 发表于 2022-3-7 17:08
这里的color数据可直接发送给TFT显示屏,若你把G弄成高位补0,那就得看显示屏是否能接受了,莫非发送给显 ...

大佬我试了下原来图片是这样的 IMG20220307170558.jpg ,改成G的最高位为0是这样的 IMG20220307165920.jpg ,颜色是有点不对。你的意思是说G的最低位补0还是最高位补0是取决于显示屏的电路吗?电路也能将数据移位?
回复

使用道具 举报

13

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2021-5-7
在线时间
102 小时
 楼主| 发表于 2022-3-8 10:38:13 | 显示全部楼层
LcwSwust 发表于 2022-3-8 09:12
电路上移位,以51单片机为例:P0口的0~6脚分别接P1口的1~7脚,P1.0接地,然后运行,
P0=x;
y=P1;

哦,多谢大佬
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-8 18:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表