功能
在嵌入式linux上, 通过操作framebuffer, 直接在显示屏上显示bmp图片
之前网上找的一些类似功能的都不靠谱, 于是自己写了一个测试程序
使用方法
编译后拷贝进开发板即可使用
./fb_show_bmp test.bmp
显示的图片由参数指定,上面指令中test.bmp为测试用的bmp格式的图片
效果
源码说明
代码说明
有部分代码需要注意一下
-
显示屏设备节点
默认使用的是/dev/fb0这个节点,如果开发板的不是这个,需要改动 -
显示屏显示一行像素的数据长度
显示屏一行的数据长度由struce fb_fix_screeninfo
中的line_length
字段决定, 而通过屏幕的分辨率计算得到的一行的数据量不一定准确.
例如一个显示屏是 800x480, bpp为32, 直接计算一行的数据长度为: 800 * (32 / 8) 个字节
但是这样计算不一定准确, 还与驱动的实现方式有关, 所以最好还是直接使用line_length
字段
-
bmp格式问题
bmp图片的数据对于显示屏来说像是上下左右颠倒了, 所以进行转换时需要处理一下
函数cursor_bitmap_format_convert()
进行了一行显示数据的左右处理
上下方向上的数据我没有进行处理, 所以最终效果看起来是上下颠倒的 -
显示屏bpp
我只测试了bpp为24/32的板子, 对于bpp为16的如果测试有问题, 可能还需要在修改下代码
源码
源码与一些测试用的bmp图片可在这里下载: https://download.csdn.net/download/bruno_mars/11267270
- fb_show_bmp.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <errno.h>
//14byte文件头
typedef struct
{
char cfType[2]; //文件类型,"BM"(0x4D42)
int cfSize; //文件大小(字节)
int cfReserved; //保留,值为0
int cfoffBits; //数据区相对于文件头的偏移量(字节)
}__attribute__((packed)) BITMAPFILEHEADER;
//__attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐
//40byte信息头
typedef struct
{
char ciSize[4]; //BITMAPFILEHEADER所占的字节数
int ciWidth; //宽度
int ciHeight; //高度
char ciPlanes[2]; //目标设备的位平面数,值为1
int ciBitCount; //每个像素的位数
char ciCompress[4]; //压缩说明
char ciSizeImage[4]; //用字节表示的图像大小,该数据必须是4的倍数
char ciXPelsPerMeter[4]; //目标设备的水平像素数/米
char ciYPelsPerMeter[4]; //目标设备的垂直像素数/米
char ciClrUsed[4]; //位图使用调色板的颜色数
char ciClrImportant[4]; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
}__attribute__((packed)) BITMAPINFOHEADER;
typedef struct
{
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char reserved;
}__attribute__((packed)) PIXEL; //颜色模式RGB
typedef struct
{
int fbfd;
char *fbp;
unsigned int xres;
unsigned int yres;
unsigned int xres_virtual;
unsigned int yres_virtual;
unsigned int xoffset;
unsigned int yoffset;
unsigned int bpp;
unsigned long line_length;
unsigned long size;
struct fb_bitfield red;
struct fb_bitfield green;
struct fb_bitfield blue;
} FB_INFO;
typedef struct
{
unsigned int width;
unsigned int height;
unsigned int bpp;
unsigned long size;
unsigned int data_offset;
} IMG_INFO;
FB_INFO fb_info;
IMG_INFO img_info;
int show_bmp(char *img_name);
static int cursor_bitmap_format_convert(char *dst,char *src, unsigned long img_len_one_line)
{
int img_len ,fb_len ;
char *p;
__u32 val;
PIXEL pix;
p