思路
一、打开图片和帧缓存驱动文件(/dev/fb0),写入帧缓存驱动文件等同于写入LCD
二、mmap映射显存(需要读写方式打开文件才可以设置共享属性)
三、偏移指向图片指针,图片头文中存放了图片格式信息(54个字节),我们只需取出颜色信息
四、读取图片像素点,BMP图片是24位的,一个像素点3个字节,像素排布为B-G-R
五、写入颜色,LCD中像素排布为A-R-G-B所以存放颜色的时候需要反向BGR->ARGB,并将A置零
六、解除映射、关闭帧缓存、关闭图片、释放申请的空间
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <error.h>
#include <sys/mman.h> //mmap函数头文件
#define LCD_DEV_PATH "/dev/fb0"
#define OPEN_DEV_FLAG O_RDWR // LCD帧缓存驱动文件打开方式
#define OPEN_BMP_FLAG O_RDONLY // BMP文件打开方式
#define LCD_H 480
#define LCD_W 800
#define MMAP_LEN LCD_H*LCD_W*4
int shoe_bmp(char *bmp_path);
int main()
{
while(1)
{
shoe_bmp("phtot/1.bmp");
}
return 0;
}
//显示图片,要显示的图片地址为参数
int shoe_bmp(char *bmp_path)
{
int lcd_fd = open(LCD_DEV_PATH, OPEN_DEV_FLAG); //以只写方式打开帧缓存驱动文件
int bmp_fd = open(bmp_path, OPEN_BMP_FLAG); //以可读可写方式打开
if (lcd_fd == -1 || bmp_fd == -1)
{
perror("open error");
return -1;
}
//映射显存 设置映射共享属性需要可读可写方式打开文件才可以共享
int *FB = mmap(NULL, MMAP_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0); //映射显存
if(FB == MAP_FAILED)
{
perror("mmap error");
return -1 ;
}
char *rgb_buf = (char *)malloc(sizeof(char) * LCD_H * LCD_W * 3); //存取图片中的像素点,每个像素点3个字节,BGR
if (rgb_buf == (char *)-1)
{
perror("malloc error");
return -1;
}
/*解决图片偏移问题*/
//偏移指针,图片文件头存放了图片格式,取像素点不需要取出
lseek(bmp_fd, 54, SEEK_SET); //存放了54个字节头信息
//读取图片BGR存放在rgb_buf中,图片中RGB存放是反向的取出为--->BGR
int read_ret = read(bmp_fd, rgb_buf, LCD_H * LCD_W * 3);
if (read_ret == -1)
{
perror("read bmp error");
return -1;
}
/*解决图片显示不全、色差、翻转问题*/
//将BGR转换成ARGB,并将存储内容翻转
for (int y = 0; y < LCD_H; y++)
{
for (int x = 0; x < LCD_W; x++)
{
// A R G B
*(FB + 800 * (LCD_H - 1 - y) + x) = 0x00 << 24 | *(rgb_buf + 3 * (800 * y + x) + 2) << 16 | *(rgb_buf + 3 * (800 * y + x) + 1) << 8 | *(rgb_buf + 3 * (800 * y + x));
//*(FB + 800 * (LCD_H - 1 - y) + x) = *(rgb_buf + n) | *(rgb_buf + n + 1) << 8 | *(rgb_buf + n + 2) << 16;
}
}
munmap(FB,MMAP_LEN);
close(lcd_fd);
close(bmp_fd);
free(rgb_buf);
return 0;
}