【Linux下6818开发板(ARM)】在液晶屏上显示RGB颜色和BMP图片

chatgpt/2023/10/4 7:16:56
  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

        在嵌入式系统的开发中,我们经常需要在液晶屏上显示一些信息,如文本、图片等。在本篇文章中,我将解析两个C语言的例程,这些例程分别用于在液晶屏上显示不同的RGB颜色和显示BMP图片。

一、在液晶屏上显示RGB颜色

        RGB颜色想必大家都懂吧,简单介绍一下:

        RGB是一种用于表示颜色的色彩模型,它是英文单词"Red(红色)"、"Green(绿色)"和"Blue(蓝色)"的缩写。在RGB色彩模型中,每种颜色由红色、绿色和蓝色三个分量的不同强度组成,通过调整这三个分量的数值,可以得到各种不同的颜色。

        在RGB色彩模型中,每个颜色分量的取值范围通常是0到255。数值为0表示没有该颜色分量,而数值为255表示该颜色分量的最大强度。因此,RGB颜色可以用一个三元组(R, G, B)来表示,其中R表示红色分量的强度,G表示绿色分量的强度,B表示蓝色分量的强度。

        例如,纯红色的RGB颜色表示为(255, 0, 0),即红色分量为最大强度,而绿色和蓝色分量均为0。类似地,纯绿色的RGB颜色表示为(0, 255, 0)纯蓝色的RGB颜色表示为(0, 0, 255),我们通常在编程中用0x00ff0000的十六进制表示红色

        通过调整RGB颜色的三个分量的数值,可以得到各种不同的颜色,包括所有可见的颜色。由于RGB色彩模型在计算机图形和显示技术中得到广泛应用,所以它是最常用的色彩模型之一。

        下面来看一下综合例程:

//在屏幕上交替的显示红绿蓝三色
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <errno.h>		
#include <time.h>		
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>		//帧缓冲设备的结构体定义在这个里面#define LCDDEV		"/dev/fb0"			
#define LCDSIZE  800*480*4struct color {unsigned int red;unsigned int green;unsigned int blue;
};void input_color(int *lcd_buf, int color)
{int x, y;for ( y=0; y<480; y++){for(x=0; x<800; x++){lcd_buf[y*800 + x] = color;	}}
}void output_color(int color)
{// 1. 打开液晶屏设备int lcd_fd = open(LCDDEV, O_RDWR);if(lcd_fd == -1){perror("open lcd fail");exit(errno);}// 给液晶屏文件映射一块内存// void *mmap(void *addr, size_t len, int prot, int flags,int fildes, off_t off); int *fb = mmap(NULL, LCDSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);if(fb == MAP_FAILED){perror("mmap fail");exit(errno);}int lcd_buf[800*480] ={0}; input_color(lcd_buf,color);memcpy(fb,lcd_buf,LCDSIZE);// 3. 关闭液晶屏munmap(fb, LCDSIZE);close(lcd_fd);}				
int main(int argc, char *argv[])
{// 2. 初始化颜色值struct color rgb = { .red = 0x00ff0000, .green = 0x0000ff00, .blue = 0x000000ff };while(1){output_color(rgb.red);sleep(1);output_color(rgb.green);sleep(1);output_color(rgb.blue);sleep(1);}return 0;
}

        这个代码的主要思路是,首先定义一个颜色结构体,然后创建一个颜色缓冲区,将颜色数据填充到缓冲区中,最后将缓冲区的内容写入到液晶屏设备中。

        在代码中,我们首先定义了一个颜色结构体struct color,它包含了3个成员:红色、绿色和蓝色。然后,我们定义了一个input_color函数,该函数的主要作用是将颜色数据填充到颜色缓冲区中。output_color函数则负责将颜色缓冲区的内容写入到液晶屏设备中。

        在main函数中,我们首先初始化了颜色的值,然后在一个无限循环中,不断的将红色、绿色和蓝色的颜色信息写入到液晶屏设备中,每次写入后暂停1秒。

二、在液晶屏上显示BMP图片

        这个操作就像把大象放进冰箱需要几步这个问题一样,第一步打开液晶屏,第二步导入bmp格式的图片,第三步关闭液晶屏,顺着这个思路我们很快就能写出如下程序,当然细节处怎么做到还需自己研究一下哦,其实很简单,主要用到了像素转换的思想

        像素转换代码:color = bmp_buf[k] | bmp_buf[k+1]<<8 | bmp_buf[k+2]<<16;

  • 在这个循环中,我们使用ij变量遍历每个像素点的行和列,同时使用k变量来遍历bmp_buf缓冲区,处理每个像素的BGR颜色数据。
  • 由于BMP图像是BGR顺序存储的,我们通过位运算将3个字节的颜色数据合成为一个32位的像素颜色值。
  • 位运算操作的目的是将BGR颜色数据拼接成一个32位整数的颜色值,其中高8位为0(alpha通道,不透明度),接下来8位为红色值,再接下来8位为绿色值,最低8位为蓝色值。

        另外还需搞清楚,BMP图片的像素数据是从左到右,从下到上存储的,而液晶屏的读取是从左往右,从上往下,刚好是上下颠倒。

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <errno.h>		
#include <time.h>		
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>		//帧缓冲设备的结构体定义在这个里面#define LCDDEV		"/dev/fb0"			void show_bmp(char *name)
{// 1. 打开液晶屏设备int lcd_fd = open(LCDDEV, O_RDWR);if(lcd_fd == -1){perror("open lcd fail");exit(errno);}int bmp_fd = open(name, O_RDONLY);if(bmp_fd == -1){perror("open bmp fail");exit(errno);}// 给液晶屏文件映射一块内存// void *mmap(void *addr, size_t len, int prot, int flags,int fildes, off_t off);// int *fb = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);if(fb == MAP_FAILED){perror("mmap fail");exit(errno);}// 先跳过54字节的文件头和信息头lseek(bmp_fd, 54, SEEK_SET);// 读取位图数据(图像的BGR颜色数据))char bmp_buf[800*480*3] = {0};read(bmp_fd, bmp_buf, 800*480*3);int i, j, k = 0;int color = 0;//液晶屏的扫描方式是:从上到下,从左到右//而bmp图像数据的存储方式是:从左到右,从下到上//所以要反着写入,就能解决翻转问题for (i = 479; i >= 0; i--) {for (j = 0; j < 800; j++) {color = bmp_buf[k] | bmp_buf[k + 1] << 8 | bmp_buf[k + 2] << 16;// 像素转换k += 3;fb[i * 800 + j] = color;// 写入液晶屏}}munmap(fb, 800*480*4);close(bmp_fd);// 3. 关闭液晶屏close(lcd_fd);}int main(int argc, char *argv[])
{if (argc != 2) {printf("Usage: %s <picture> \n", argv[0]);return 1;}show_bmp(argv[1]);return 0;
}

        例程的主要思路是,首先打开BMP图片文件和液晶屏设备,然后读取BMP图片的像素数据,将这些像素数据写入到液晶屏的缓冲区中,最后将缓冲区的内容写入到液晶屏设备中。

        在代码中,我们首先打开了液晶屏设备和BMP图片文件,然后创建了一个映射,这个映射将液晶屏设备的内存映射到了进程的地址空间。接着,我们从BMP图片文件中读取像素数据,将这些数据写入到液晶屏的缓冲区中。最后,我们将缓冲区的内容写入到液晶屏设备中。

三、运行

        有了代码那怎么运行呢,其实之前的博客里也教过,但是还是凑点字数,多说说,只要需要用 rz -y命令把可执行文件传给开发板就行。

         什么?又不会编译了,看这里:

        

        传统就是arm-linux-gcc ,那么快捷方法就是用alias命令把它变成一个快捷指令ag。 

四、总结

        通过这两个例程,我们可以看到在C语言中如何操作液晶屏设备,如何将颜色和图片显示到液晶屏上。这些例程提供了一个很好的起点,让我们能够理解如何在嵌入式系统中进行液晶屏的编程。希望这个文章能对你有所帮助,如果你有任何问题,欢迎在评论区留言。

        更多C语言Linux系统相关文章,关注专栏:

   手撕C语言

            玩转linux

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-5314247.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

linux快速安装Nginx

linux快速安装Nginx 安装yum依赖程序 yum install -y yum-utils 添加nginx的yum仓库 cd /etc/yum.repos.d/ 配置相应信息保存并退出 vim nginx.repo 将下边的信息复制粘贴并保存退出 [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$re…

Jotai使用笔记(一)

Jotai Jotai 是一款轻量级的状态管理工具&#xff0c;大小只有2kb&#xff0c;支持 Typescript。 1. Jotai的组成部分 store: 主要用于数据的存储、依赖的收集和更新&#xff0c;已经更新通知atom&#xff1a;创建原子&#xff0c;或者衍生新的原子useAtom&#xff1a;将ato…

日撸代码300行:第58天(符号型数据的 NB 算法)

代码来自闵老师”日撸 Java 三百行&#xff08;51-60天&#xff09;“&#xff0c;链接&#xff1a;https://blog.csdn.net/minfanphd/article/details/116975957 Naive Bayes是通过概率分布来进行分类。基础理论知识见闵老师博客[1]&#xff1a;NB 算法 (包括符号型与数值型,…

【ES】使用日志记录

1、修改操作 1、要删除Elasticsearch索引的分区下的数据 <index_name>是要删除数据的索引名称。这个命令会删除该索引下的所有数据。 POST /<index_name>/_delete_by_query {"query": {"match_all": {}} }2、删除特定条件下的数据 要删除a…

代码随想录 day44 完全背包

class Solution { public: int change(int amount, vector<int>& coins) { vector <int> dp(amount1,0); dp[0]1; for(int i0;i<coins.size();i){ for(int jcoins[i];j<amount;j){ dp[j]dp[j-coins[i]]; } } return dp[amount]; } }; 另外你这个是不能…

【TypeScript】接口类型 Interfaces 的使用理解

导语&#xff1a; 什么是 类型接口&#xff1f; 在面向对象语言中&#xff0c;接口&#xff08;Interfaces&#xff09;是一个很重要的概念&#xff0c;它是对行为的抽象&#xff0c;而具体如何行动需要由类&#xff08;classes&#xff09;去实现&#xff08;implement&#x…

C语言【怎么定义变量?】

变量定义的目的是向编译器说明在哪里创建变量的存储&#xff0c;并指明如何创建变量的存储方式。变量定义会明确指定一个数据类型&#xff0c;并包含一个或多个变量的列表。例如&#xff1a; type variable_list; 在这里&#xff0c;"type"必须是一个合法的C数据类…

【phaser微信抖音小游戏开发002】hello world!

执行效果&#xff1a; 将以下代码文本内容&#xff0c;放入到game.js中即可。目录结构如下图 import ./js/libs/weapp-adapter import ./js/libs/symbolGameGlobal.window.scrollTo () > { };//防止真机出错 import Phaser from ./js/phaser//引入Phaservar {windowWidth, …
推荐文章