GEC6818开发板显示png图片效果

前言

        在开始之前,我跟大家声明一下,这个教程不是在开发板上面显示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 ;
}

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

今天在做毕设的时候,因为有个视频播放,我想在视频暂停的时候,在视频中间显示出一个暂停的图标,没有背景的暂停图标,然后我就想起来在屏幕是显示图片的原理,最后通过验证我的想法是正确的,确实是可以通过这种方法来达到这个效果,思路在上面就说了,心血来潮写下这篇文章,记录一下我的学习,同时可以给到更多的同学起到解惑的作用,共勉!!!

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
gec6818开发板图片显示黑白重叠可能是由于以下原因之一导致的: 1. 图片格式不支持:开发板可能只支持特定的图片格式,如BMP格式。如果您尝试显示图片是其他格式,如PNG格式,可能会导致显示异常。\[2\] 2. 图片显示设置错误:开发板显示设置可能需要进行正确配置,以确保图片能够正确显示。您可以检查开发板的文档或参考相关的开发指南,了解如何正确设置图片显示参数。 3. 驱动问题:开发板的驱动程序可能存在问题,导致图片显示异常。您可以尝试更新或重新安装驱动程序,或者联系开发板的制造商获取技术支持。 请您根据具体情况检查以上可能的原因,并采取相应的解决措施来解决图片显示黑白重叠的问题。 #### 引用[.reference_title] - *1* *3* [GEC6818开发板使用和配置](https://blog.csdn.net/m0_45463480/article/details/124673151)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [GEC6818开发板显示png图片效果](https://blog.csdn.net/weixin_50722786/article/details/127183021)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三目条件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值