显示BMP图片

1.什么是BMP图片

1.1bmp概念

  • BMP是英文Bitmap(位图)的简写,它是(Windows操作系统)中的标准(图像文件格式),能够被多种Windows应用程序所支持。随着Windows操作系统的流行与丰富的Windows应用程序的开发,BMP(位图)格式理所当然地被广泛应用。这种格式的特点是包含的图像信息较丰富,几乎不进行压缩,但由此导致了它与生俱生来的缺点--占用(磁盘)空间过大。所以,目前BMP在单机上比较流行。
  • bmp图片像素排列方式为BGR
  • bmp文件的图像深度可选1bit、4bit、8bit、24bit。bmp格式图片的扫描方式为从左到右,从上到下
  • 使用bmp格式图片优点是可以很方便的得到图片像素数据,而jpg/jpeg格式需要先解压图像数据之后才可得到像素数据
  • 本平台在显示图片时选择24位位图格式
  • bmp图片前54字节不是图片数据,而是保存图片信息,例如图片名称,尺寸等
  • 所以一张bmp图片大小为800*480*3+54=1152054字节,没有透明度选项
  • 更多详细信息

1.2制作bmp图片

  • 首先下载图片,使用win自带的画图软件打开
  • 设置图片大小为800*480
  • 另存为bmp格式图片
  • 查看图片信息,可看到图片大小为1152054字节

1.3将bmp图片整到开发板上

  • 按照传统代码烧写方法,通过SecureCRT将bmp图片传输到开发板上,理论可行,然现实却需要等待若干小时。因为串口波特率为115200,即115200bit/s=112.5Byte/s=0.1kB/s,一张bmp图片大小在1M左右,可看出传输时间会非常慢
  • 鉴于以上原因,可通过U盘将图片传输到开发板上。前提是开发板已经安装好对应USB驱动
  • 将事先准备好的bmp图片拷贝到U盘上,再将U盘插到开发板上,可看到有以下信息,证明有USB设备插入且成果识别USB设备信息
[root@GEC6818 /IOT/home]#[ 1981.712000] usb 1-1.2: new high-speed USB device number 3 using nxp-ehci
[ 1981.789000] usb 1-1.2: New USB device found, idVendor=048d, idProduct=1234
[ 1981.790000] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1981.798000] usb 1-1.2: Product: UDisk           
[ 1981.802000] usb 1-1.2: Manufacturer: General 
[ 1981.806000] usb 1-1.2: SerialNumber: Љ
[ 1981.813000] scsi0 : usb-storage 1-1.2:1.0
[ 1982.819000] scsi 0:0:0:0: Direct-Access     General  UDisk            5.00 PQ: 0 ANSI: 2
[ 1982.825000] sd 0:0:0:0: [sda] 32768000 512-byte logical blocks: (16.7 GB/15.6 GiB)
[ 1982.827000] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 1982.835000] sd 0:0:0:0: [sda] Write Protect is off
[ 1982.840000] sd 0:0:0:0: [sda] No Caching mode page present
[ 1982.844000] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 1982.855000] sd 0:0:0:0: [sda] No Caching mode page present
[ 1982.856000] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 1982.863000]  sda:
[ 1982.868000] sd 0:0:0:0: [sda] No Caching mode page present
[ 1982.870000] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 1982.875000] sd 0:0:0:0: [sda] Attached SCSI removable disk
  • 去到/mnt目录下可看到相关文件夹
[root@GEC6818 /IOT/home]#cd /mnt/
[root@GEC6818 /mnt]#ls
sd     udisk
[root@GEC6818 /mnt]#
  • 之后会惊喜地发现该文件夹下啥都没有^x^
[root@GEC6818 /mnt]#ls -l sd
total 0
[root@GEC6818 /mnt]#ls -l udisk/
total 0
[root@GEC6818 /mnt]#
  • 此处需要通过mount指令挂载U盘
# 创建挂载文件夹
[root@GEC6818 /mnt]#mkdir usb
[root@GEC6818 /mnt]#ls
sd     udisk  usb

# 挂载U盘,将dev目录下的设备文件sda映射到刚刚创建的usb文件夹下
[root@GEC6818 /mnt]#mount /dev/sda /mnt/usb/

# 此处进入usb文件下面,就可看到U盘内文件了
[root@GEC6818 /mnt]#cd usb/
[root@GEC6818 /mnt/usb]#ls
1.bmp
2.bmp
201730133027
3.bmp
????.pdf
????2020
?????
???????.pdf
????????.doc
??????????.docx
??Arduino.pdf
AT89C51 ?????????????
Alarms
Android
Bandicam???
Chinatelecom_JSPortal
DCIM
Download
EasyX_2018???.exe
Fritzing0.9.3b.dmg
LOST.DIR
Movies
Music
Notifications
Pictures
Podcasts
Processing.app
RavV17std.exe
Ringtones
System Volume Information
Wireless LAN_Atheros_12.0.0.191_W10x64_A.zip
[Beginning.Arduino].Michael.McRoberts.???.pdf
arduino-1.8.7-macosx.zip
arduino??????.pdf
hq.txt
liz.txt
processing-3.4-macosx.zip
processing-3.4-windows64.zip
record
video
[root@GEC6818 /mnt/usb]#
  • 最终通过cp指令就可随心所欲地copy了哈
  • 取消挂载指令为umount /mnt/usb,类似win上的弹出U盘

2.屏幕适配bmp图片

2.1适配方法

  • 由于bmp图片像素排列方式不为RGB,所以需要我们通过移位操作完成像素重新排列的操作
  • LCD屏像素排列为ARGB,bmp图片像素排列为BGR
  • 针对一个像素点,可通过移位操作将bmp像素排列改为LCD屏像素排列
/*bmp格式*/
B   G   R
/*LCD排列*/
A   R   G   B
/*bmp--->LCD*/
(R<<16)|(G<<8)|(B)

2.2示例代码

  • 循环显示图片
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

/*全局变量,保存内存映射后的地址*/
int *p = NULL;
/*全局变量,保存驱动文件设备描述符*/
int fd;
/*二维数组,保存图片名称*/
char pic[3][10] = {"1.bmp", "2.bmp", "3.bmp"};

/*LCD屏幕初始化,即进行打开显示驱动文件、内存映射等工作*/
int lcd_init(void)
{
    fd = open("/dev/fb0", O_RDWR);
    if(fd == -1)
    {
        printf("open file error\n");
        return -1;
    }
    /*内存映射*/
    p = mmap(NULL, 800 * 480 * 4, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
    if(p == NULL)
    {
        printf("mmap error\n");
        close(fd);
        return -1;
    }
    return 0;
}
/*描绘像素点,即告诉每个像素点对应该显示的色域值*/
void lcd_draw_point(int x, int y, int color)
{
    *(p + y * 800 + x) = color;
}
/*将图片从bmp格式转换为LCD屏的显示格式,操作单位是像素点*/
int lcd_draw_bmp(char *pic_name)
{
    /*打开bmp图片文件*/
    int pic_fd = open(pic_name, O_RDWR);
    /*给每张图片申请缓存地址,注意申请大小*/
    char pic_buff[800 * 480 * 3] = {0};
    /*保存R、G、B像素值,单位是1字节*/
    char red, green, blue;
    int color;
    int p = 0;
    if(pic_fd < 0)
    {
        printf("open picture error\n");
        return -1;
    }
    
    /*根据bmp格式,应该跳过前54字节的内容*/
    lseek(pic_fd, 54, SEEK_SET);
    /*将bmp图片中的像素内容写入缓存区*/
    read(pic_fd, pic_buff, 800 * 480 * 3);
    /*像素点移位,适配LCD屏幕格式*/
    for(int i = 0; i < 480; i++)
    {
        for(int j = 0; j < 800; j++)
        {
            /*读bmp像素点中的B色域*/
            blue = pic_buff[p++];
            /*读bmp像素点中的G色域*/
            green = pic_buff[p++];
            /*读bmp像素点中的R色域*/
            red = pic_buff[p++];
            /*移位操作将BGR转RGB,将转换后结果保存到color(4字节)中间变量中*/
            color = (blue) | (green<<8) | (red<<16);
            /*将移动好的像素值写入对应位置*/
            //lcd_draw_point(j, i, color);//BUG版本,此举图像将按照镜面方式显示
            lcd_draw_point(j, 479 - i, color);//修复版本,更改刷新方式为从左到右,从下往上
        }
    }
    close(pic_fd);
}
int main()
{
    if(lcd_init() != 0)
    {
        printf("lcd init error\n");
        close(fd);
        return -1;
    }
    while (1)
    {
        /*循环显示3张图片*/
        for(int i = 0; i < 3; i++)
        {
            lcd_draw_bmp(pic[i]);
            sleep(1);
        }
    }
    /*解除映射*/
    munmap(p, 800 * 480 * 4);
    /*指针置空,防止野指针出现*/
    p = NULL;
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352