- (??? ),hello我是祐言
- 博客主頁:C語言基礎(chǔ),Linux基礎(chǔ),軟件配置領(lǐng)域博主??
- 快上??,一起學(xué)習(xí)!
- 送給讀者的一句雞湯??:
- 集中起來的意志可以擊穿頑石!
- 作者水平很有限,如果發(fā)現(xiàn)錯(cuò)誤,可在評(píng)論區(qū)指正,感謝??
????????在嵌入式系統(tǒng)的開發(fā)中,我們經(jīng)常需要在液晶屏上顯示一些信息,如文本、圖片等。在本篇文章中,我將解析兩個(gè)C語言的例程,這些例程分別用于在液晶屏上顯示不同的RGB顏色和顯示BMP圖片。
一、在液晶屏上顯示RGB顏色
????????RGB顏色想必大家都懂吧,簡單介紹一下:
????????RGB是一種用于表示顏色的色彩模型,它是英文單詞"Red(紅色)"、"Green(綠色)"和"Blue(藍(lán)色)"的縮寫。在RGB色彩模型中,每種顏色由紅色、綠色和藍(lán)色三個(gè)分量的不同強(qiáng)度組成,通過調(diào)整這三個(gè)分量的數(shù)值,可以得到各種不同的顏色。
????????在RGB色彩模型中,每個(gè)顏色分量的取值范圍通常是0到255。數(shù)值為0表示沒有該顏色分量,而數(shù)值為255表示該顏色分量的最大強(qiáng)度。因此,RGB顏色可以用一個(gè)三元組(R, G, B)來表示,其中R表示紅色分量的強(qiáng)度,G表示綠色分量的強(qiáng)度,B表示藍(lán)色分量的強(qiáng)度。
????????例如,純紅色的RGB顏色表示為(255, 0, 0),即紅色分量為最大強(qiáng)度,而綠色和藍(lán)色分量均為0。類似地,純綠色的RGB顏色表示為(0, 255, 0),純藍(lán)色的RGB顏色表示為(0, 0, 255),我們通常在編程中用0x00ff0000的十六進(jìn)制表示紅色。
????????通過調(diào)整RGB顏色的三個(gè)分量的數(shù)值,可以得到各種不同的顏色,包括所有可見的顏色。由于RGB色彩模型在計(jì)算機(jī)圖形和顯示技術(shù)中得到廣泛應(yīng)用,所以它是最常用的色彩模型之一。
????????下面來看一下綜合例程:
//在屏幕上交替的顯示紅綠藍(lán)三色
#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> //幀緩沖設(shè)備的結(jié)構(gòu)體定義在這個(gè)里面
#define LCDDEV "/dev/fb0"
#define LCDSIZE 800*480*4
struct 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. 打開液晶屏設(shè)備
int lcd_fd = open(LCDDEV, O_RDWR);
if(lcd_fd == -1)
{
perror("open lcd fail");
exit(errno);
}
// 給液晶屏文件映射一塊內(nèi)存
// 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. 關(guān)閉液晶屏
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;
}
????????這個(gè)代碼的主要思路是,首先定義一個(gè)顏色結(jié)構(gòu)體,然后創(chuàng)建一個(gè)顏色緩沖區(qū),將顏色數(shù)據(jù)填充到緩沖區(qū)中,最后將緩沖區(qū)的內(nèi)容寫入到液晶屏設(shè)備中。
????????在代碼中,我們首先定義了一個(gè)顏色結(jié)構(gòu)體struct color
,它包含了3個(gè)成員:紅色、綠色和藍(lán)色。然后,我們定義了一個(gè)input_color
函數(shù),該函數(shù)的主要作用是將顏色數(shù)據(jù)填充到顏色緩沖區(qū)中。output_color
函數(shù)則負(fù)責(zé)將顏色緩沖區(qū)的內(nèi)容寫入到液晶屏設(shè)備中。
? ? ? ? 在main
函數(shù)中,我們首先初始化了顏色的值,然后在一個(gè)無限循環(huán)中,不斷的將紅色、綠色和藍(lán)色的顏色信息寫入到液晶屏設(shè)備中,每次寫入后暫停1秒。
二、在液晶屏上顯示BMP圖片
????????這個(gè)操作就像把大象放進(jìn)冰箱需要幾步這個(gè)問題一樣,第一步打開液晶屏,第二步導(dǎo)入bmp格式的圖片,第三步關(guān)閉液晶屏,順著這個(gè)思路我們很快就能寫出如下程序,當(dāng)然細(xì)節(jié)處怎么做到還需自己研究一下哦,其實(shí)很簡單,主要用到了像素轉(zhuǎn)換的思想:
????????像素轉(zhuǎn)換代碼:color = bmp_buf[k] | bmp_buf[k+1]<<8 | bmp_buf[k+2]<<16;
- 在這個(gè)循環(huán)中,我們使用
i
和j
變量遍歷每個(gè)像素點(diǎn)的行和列,同時(shí)使用k
變量來遍歷bmp_buf
緩沖區(qū),處理每個(gè)像素的BGR顏色數(shù)據(jù)。 - 由于BMP圖像是BGR順序存儲(chǔ)的,我們通過位運(yùn)算將3個(gè)字節(jié)的顏色數(shù)據(jù)合成為一個(gè)32位的像素顏色值。
- 位運(yùn)算操作的目的是將BGR顏色數(shù)據(jù)拼接成一個(gè)32位整數(shù)的顏色值,其中高8位為0(alpha通道,不透明度),接下來8位為紅色值,再接下來8位為綠色值,最低8位為藍(lán)色值。
? ? ? ? 另外還需搞清楚,BMP圖片的像素?cái)?shù)據(jù)是從左到右,從下到上存儲(chǔ)的,而液晶屏的讀取是從左往右,從上往下,剛好是上下顛倒。
#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> //幀緩沖設(shè)備的結(jié)構(gòu)體定義在這個(gè)里面
#define LCDDEV "/dev/fb0"
void show_bmp(char *name)
{
// 1. 打開液晶屏設(shè)備
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);
}
// 給液晶屏文件映射一塊內(nèi)存
// 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字節(jié)的文件頭和信息頭
lseek(bmp_fd, 54, SEEK_SET);
// 讀取位圖數(shù)據(jù)(圖像的BGR顏色數(shù)據(jù)))
char bmp_buf[800*480*3] = {0};
read(bmp_fd, bmp_buf, 800*480*3);
int i, j, k = 0;
int color = 0;
//液晶屏的掃描方式是:從上到下,從左到右
//而bmp圖像數(shù)據(jù)的存儲(chǔ)方式是:從左到右,從下到上
//所以要反著寫入,就能解決翻轉(zhuǎn)問題
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;// 像素轉(zhuǎn)換
k += 3;
fb[i * 800 + j] = color;// 寫入液晶屏
}
}
munmap(fb, 800*480*4);
close(bmp_fd);
// 3. 關(guān)閉液晶屏
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圖片文件和液晶屏設(shè)備,然后讀取BMP圖片的像素?cái)?shù)據(jù),將這些像素?cái)?shù)據(jù)寫入到液晶屏的緩沖區(qū)中,最后將緩沖區(qū)的內(nèi)容寫入到液晶屏設(shè)備中。
????????在代碼中,我們首先打開了液晶屏設(shè)備和BMP圖片文件,然后創(chuàng)建了一個(gè)映射,這個(gè)映射將液晶屏設(shè)備的內(nèi)存映射到了進(jìn)程的地址空間。接著,我們從BMP圖片文件中讀取像素?cái)?shù)據(jù),將這些數(shù)據(jù)寫入到液晶屏的緩沖區(qū)中。最后,我們將緩沖區(qū)的內(nèi)容寫入到液晶屏設(shè)備中。
三、運(yùn)行
? ? ? ? 有了代碼那怎么運(yùn)行呢,其實(shí)之前的博客里也教過,但是還是湊點(diǎn)字?jǐn)?shù),多說說,只要需要用 rz -y命令把可執(zhí)行文件傳給開發(fā)板就行。
? ? ? ? ?什么?又不會(huì)編譯了,看這里:
????????
? ? ? ? 傳統(tǒng)就是arm-linux-gcc ,那么快捷方法就是用alias命令把它變成一個(gè)快捷指令ag。?
四、總結(jié)
????????通過這兩個(gè)例程,我們可以看到在C語言中如何操作液晶屏設(shè)備,如何將顏色和圖片顯示到液晶屏上。這些例程提供了一個(gè)很好的起點(diǎn),讓我們能夠理解如何在嵌入式系統(tǒng)中進(jìn)行液晶屏的編程。希望這個(gè)文章能對(duì)你有所幫助,如果你有任何問題,歡迎在評(píng)論區(qū)留言。
????????更多C語言和Linux系統(tǒng)相關(guān)文章,關(guān)注專欄:
? ?手撕C語言文章來源:http://www.zghlxwxcb.cn/news/detail-716266.html
? ? ? ? ? ? 玩轉(zhuǎn)linux文章來源地址http://www.zghlxwxcb.cn/news/detail-716266.html
??寫在最后
- 今天的分享就到這啦~
- 覺得博主寫的還不錯(cuò)的煩勞?
一鍵三連喔
~ - ??感謝關(guān)注??
到了這里,關(guān)于【Linux下6818開發(fā)板(ARM)】在液晶屏上顯示RGB顏色和BMP圖片的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!