設計一個程式,該程式在執行之後自動播放一段開機動畫,開機動畫結束後可以調轉到登入介面,登入介面有2個按鈕,分別是登入和退出,點選登入之後可以顯示系統主介面。主介面自擬,要求主介面有一個返回按鈕,點選返回按鈕可以回到登入介面。(不使用goto)
定義全域性變數
int cnt = 0;
int x, y;
int *lcd_mp;
將JPG格式的圖片顯示在lcd螢幕的函式介面:
/******************************************************
*
* name : read_JPEG_file
* function : 將JPG格式的圖片顯示在lcd螢幕
* argument
* @filename :圖片路徑
* @start_x :圖片顯示在lcd螢幕的x軸
* @start_y :圖片顯示在lcd螢幕的y軸
*
* retval : 成功為1,否則為0
* author : Dazz
* date : 2024/5/14
* note : None
*
* *******************************************************/
int read_JPEG_file(char *filename, int start_x, int start_y)
{
//(1) 建立解碼物件,並且對解碼物件進行初始化,另外需要建立錯誤處理物件,並和解碼物件進行關聯
// 建立jpeg解碼物件
struct jpeg_decompress_struct cinfo;
// 建立錯誤處理物件
struct jpeg_error_mgr jerr;
// 將錯誤物件和解碼物件進行關聯
cinfo.err = jpeg_std_error(&jerr);
// 初始化解碼物件
jpeg_create_decompress(&cinfo);
//(2) 開啟待解碼的jpg圖片,使用fopen的時候需要新增選項”b”,以二進位制方式開啟檔案!
FILE *infile;
if ((infile = fopen(filename, "rb")) == NULL)
{
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
// 指定資料
jpeg_stdio_src(&cinfo, infile);
//(3) 讀取待解碼圖片的檔案頭,並把影像資訊和解碼物件進行關聯,透過解碼物件對jpg圖片進行解碼
(void)jpeg_read_header(&cinfo, TRUE);
//(5) 開始對jpg圖片進行解碼,呼叫函式之後開始解碼,可以得到影像寬、影像高等資訊!
(void)jpeg_start_decompress(&cinfo);
int row_stride;
row_stride = cinfo.output_width * cinfo.output_components; // 計算一行的大小
unsigned char *buffer; /* Output row buffer 定義一個緩衝區 */
buffer = calloc(1, row_stride);
int data = 0;
while (cinfo.output_scanline < cinfo.output_height)
{
(void)jpeg_read_scanlines(&cinfo, &buffer, 1); // 從上到下,從左到右 RGB RGB RGB RGB
for (int i = 0; i < cinfo.output_width; ++i) // 012 345
{
data |= buffer[3 * i] << 16; // R
data |= buffer[3 * i + 1] << 8; // G
data |= buffer[3 * i + 2]; // B
// 把畫素點寫入到LCD的指定位置
lcd_mp[800 * start_y + start_x + 800 * (cinfo.output_scanline - 1) + i] = data;
data = 0;
}
}
//(7) 在所有的影像資料都已經解碼完成後,則呼叫函式完成解碼即可,然後釋放相關資源!
(void)jpeg_finish_decompress(&cinfo);
// 釋放解碼物件
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 1;
}
開啟觸控式螢幕,直到使用者點選"登入"的位置的函式介面:
/******************************************************
*
* name : GeTouchVal_st
* function : 開啟觸控式螢幕,直到使用者點選"登入"的位置
* argument : 開啟觸控式螢幕的返回值
* retval : None
* author : Dazz
* date : 2024/5/14
* note : None
*
* *******************************************************/
void GeTouchVal_st(int ts_fd)
{
// 2.讀取輸入裝置的資訊
struct input_event ts_event;
while (1)
{
read(ts_fd, &ts_event, sizeof(ts_event));
// 3.分析讀取的裝置資訊 (type + code + value)
if (ts_event.type == EV_ABS) // 說明是觸控式螢幕
{
if (ts_event.code == ABS_X) // 說明是X軸
{
cnt++;
x = ts_event.value * 800 / 1024;
}
if (ts_event.code == ABS_Y) // 說明是Y軸
{
cnt++;
y = ts_event.value * 480 / 600;
}
if (cnt >= 2)
{
printf("x = %d\t", x); // 輸出X軸座標
printf("y = %d\n", y); // 輸出Y軸座標
cnt = 0;
}
}
if (x > 585 && x < 789 && y > 100 && y < 209)
break;
}
}
開啟觸控式螢幕,直到使用者點選"返回"的位置的函式介面:
/******************************************************
*
* name : GeTouchVal_sp
* function : 開啟觸控式螢幕,直到使用者點選"返回"的位置
* argument : 開啟觸控式螢幕的返回值
* retval : None
* author : Dazz
* date : 2024/5/14
* note : None
*
* *******************************************************/
void GeTouchVal_sp(int ts_fd)
{
// 2.讀取輸入裝置的資訊
struct input_event ts_event;
while (1)
{
read(ts_fd, &ts_event, sizeof(ts_event));
// 3.分析讀取的裝置資訊 (type + code + value)
if (ts_event.type == EV_ABS) // 說明是觸控式螢幕
{
if (ts_event.code == ABS_X) // 說明是X軸
{
cnt++;
x = ts_event.value * 800 / 1024;
}
if (ts_event.code == ABS_Y) // 說明是Y軸
{
cnt++;
y = ts_event.value * 480 / 600;
}
if (cnt >= 2)
{
printf("x = %d\t", x); // 輸出X軸座標
printf("y = %d\n", y); // 輸出Y軸座標
cnt = 0;
}
}
if (x > 35 && x < 135 && y > 2 && y < 111)
break;
}
}
主函式:
int main(int argc, char const *argv[])
{
//開啟LCD open
int lcd_fd = open("/dev/fb0", O_RDWR);
// 對LCD進行記憶體對映 mmap
lcd_mp = (int *)mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0);
// 顯示gif
char gif_buf[128] = "0";
for (int i = 0; i < 60; i++)
{
sprintf(gif_buf, "./gif/Frame%d.jpg", i);
read_JPEG_file(gif_buf, 0, 0);
usleep(1000 * 1000 / 24);
}
// 開啟觸控式螢幕
int ts_fd = open("/dev/input/event0", O_RDWR);
while (1)
{
read_JPEG_file("./start.jpg", 0, 0);
GeTouchVal_st(ts_fd);
read_JPEG_file("./stop.jpg", 0, 0);
GeTouchVal_sp(ts_fd);
}
//關閉檔案
close(ts_fd);
return 0;
}