GEC6818开发板显示png图片效果

软件开发大郭
0 评论
/
67 阅读
/
4729 字
11 2023-02

前言

在开始之前,我跟大家声明一下,这个教程不是在开发板上面显示png格式的图片,而是打开的是bmp格式的图片文件,显示成为png格式图片的效果。

思路

假设你们已经学会了如何在开发板上面显示bmp格式的图片了,那么我们知道的png格式图片在显示的时候是不会把背景显示出来的,所以我的猜想是png格式的图片,除了要显示的区域外,其他像素点都是存白色的,RGB值为0xFFFFFF;一个像素点3个字节,记住这个点,很重要。

实现思路:就是在映射图片像素点在屏幕上的时候,遇到像素点的值为0x00FFFFFF的时候就跳过,不要这些存白的像素点映射在屏幕上面即可。

原理

我们熟知的图片都是有一个个像素点集合而成的,每个像素点的颜色都是各自的RGB值组合而成,RGB是什么,是我们熟悉的三原色 红-R ,绿-G ,蓝-B ,他们可以组合形成各种各样的颜色,我们bmp格式的图片文件是不经过压缩的,所以里面存储的像素点的数据是最原始的RGB,这也是我们选bmp格式图片的缘由。

注意一点的是,bmp在存储图片RGB数据的时候,以BGR的顺序存储的,而且上下是颠倒的,所以我们在映射的顺序也要颠倒才行;

    我们开发板的屏幕的像素点不仅仅是由RGB组成,在其前面还有一个A,也就是我们屏幕像素点是ARGB,一般情况下我们都不会去理会前面的那个A,一个像素点ARGB占4个字节大小,所以在把图片显示在屏幕上有几个步骤;

    1、把bmp图片文件读取到系统bmp_buf[ ](即一个数组里面);

    2、把bmp_buf里面BGR 数据,转换成屏幕像素点的格式ARGB,放到 buf 数组里面;

    3、将 buf 里面的ARGB 像素点一个个的映射在屏幕的像素点上面,记得颠倒过来,

最关键的步骤;

遇到存白色的像素点利用 continue 语句跳开,

for(y=start_y,j=0; y<(start_y+high),j<high; y++,j++)
{
for(x=start_x,i=0; x<(start_x+width),i<width; x++,i++)
{
if(buff[(high-1-j)*width+i] == 0x00ffffff)
continue;
*(mem_p+y*800+x) = buff[(high-1-j)*width+i];
}
}

源码

show_bmp.c

#include <stdio.h>
#include <dlfcn.h>  // 动态加载动态库的头文件:dlopen()、dlsym()
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
 
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/mman.h>
struct bitmap_header
{
	int16_t type;
	int32_t size; // 图像文件大小
	int16_t reserved1;
	int16_t reserved2;
	int32_t offbits; // bmp图像数据偏移量
}__attribute__((packed));
 
struct bitmap_info
{
	int32_t size;   // 本结构大小	
	int32_t width;  // 图像宽
	int32_t height; // 图像高
	int16_t planes;
 
	int16_t bit_count; // 色深
	int32_t compression;
	int32_t size_img; // bmp数据大小,必须是4的整数倍
	int32_t X_pel;
	int32_t Y_pel;
	int32_t clrused;
	int32_t clrImportant;
}__attribute__((packed));
 
// 以下结构体不一定存在于BMP文件中,除非:
// bitmap_info.compression为真
struct rgb_quad
{
	int8_t blue;
	int8_t green;
	int8_t red;
	int8_t reserved;
}__attribute__((packed));
 
 
#define FB_FILE  "/dev/fb0"
 
unsigned int *mem_p;
 
int lcd_fd;
// BMP格式头规范
int lcd_init(void);
int lcd_uninit(void);
int show_bmp_png(const char *pathname,int start_x, int start_y);
 
int lcd_init(void)
{
    //打开file.txt文件, 文件不存在,则打开失败,如果使用O_CREAT,那必须要添加文件权限。
    lcd_fd = open(FB_FILE, O_RDWR);
    if(lcd_fd == -1)
    {
        printf("open a.txt fail\n");
        return -1;
    }   
 
    //屏幕映射
    mem_p = (unsigned int *)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    if(mem_p == MAP_FAILED)
    {
        printf("mmap fail\n");
    }
 
    return 0;
}
 
int lcd_uninit(void)
{
   // 解除映射
    munmap(mem_p, 800*480*4);
    close(lcd_fd);
 
}
 
 
/*
    参数说明:*pathname-----图片路径
              start_x--------在屏幕的哪个位置显示-x轴  
              start_y--------在屏幕的哪个位置显示-y轴  
*/
int show_bmp_png(const char *pathname,int start_x, int start_y)
{
    int width, high; //图片亮度与高度
    int i, j, x, y;
	// 读取BMP格式头,获取图片信息
	struct bitmap_header header;
	struct bitmap_info info;
	struct rgb_quad quad;
 
	int bmp_fd = open(pathname, O_RDONLY);
    if(bmp_fd == -1)
    {
        printf("open bmp fail\n");
        return -1;
    }
    //跳过54个字节头
 
 
        // 第一、二个结构体是必有信息
	read(bmp_fd, &header, sizeof(header));
	read(bmp_fd, &info, sizeof(info));
 
    width = info.width;
    high  = info.height;
 
    if(start_x+width > 800 || start_y+high > 480)
    {
        printf("%s图片显示溢出!\n",pathname);
        close(bmp_fd);
        return -1;
    }
    //变长数组
    unsigned char bmpbuff[width*high*3];
    unsigned int buff[width*high];
    unsigned int tmpbuff[width*high];
 
 
    read(bmp_fd, bmpbuff, sizeof(bmpbuff));
 
    for(i=0; i<width*high; i++)
    {
        buff[i] = bmpbuff[3*i+0] | bmpbuff[3*i+1]<<8 | bmpbuff[3*i+2]<<16;
    }
 
 
 
//正真显示图片
 
    for(y=start_y,j=0; y<(start_y+high),j<high; y++,j++)
    {
        for(x=start_x,i=0; x<(start_x+width),i<width; x++,i++)
        {
            if(buff[(high-1-j)*width+i] == 0x00ffffff)
                continue;
            *(mem_p+y*800+x) = buff[(high-1-j)*width+i];
        }
    }
 
    close(bmp_fd);
 
    return 0;
}
 
 
int main()
{
    show_bmp_png("1.bmp",0,0);
    return 0 ;
}

里面有专门读取图片长度宽度大小信息的结构体,可以得知图片的大小。

    暂无数据