赞
踩
当前实现了触摸屏控制左右划切换以及上下划删除,3秒自动切换图片,显示触摸动作(不需要可自行删除)。
图片删除采用删除标记法,通过一个数组对图片信息进行记录,删除则在相应位置赋1,使得在切换图片时跳过该图片。
更改了图片数量后请在代码中修改 PicTotal 的值。
picX.bmp 相册图片X为图片编号从0开始编排序号,分辨率为 800x480。
deleted.bmp 为删除时在屏幕中间显示的200x200垃圾桶图标。
nopic.bmp 为图片全部被删除时显示的无图片200x170图标。

以下为代码:
/******************************************************************************** * @File name: album.c * @Author: MaxMiku 阿杰 * @Version: 0.2 * @Date: 2022-11-24 * @Description: Arm development board album. ********************************************************************************/ #include <fcntl.h> #include <linux/input.h> //必须添加 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <time.h> #include <unistd.h> #define PicTotal 4 //图片数量 从0开始 int fd = -1, tsfd = -1; //设备号 int *lcd; // lcd映射 time_t t; //时间 //触摸事件 0xAABBBCCC // AA: 事件类型 0x00无事件 0x01点击 0x02上划 0x03下滑动 0x04 左滑 0x05右滑动 0x06按下 touchEvent>>24 // BBB: x轴坐标 touchEvent <<8 >>20 // CCC: y轴坐标 touchEvent <<20 >>20 int touchEvent = 0x01 << 24 | 250 << 12 | 140; pthread_t thread_touchDeal; //触摸线程 char threadLock = 0; //线程锁 位 7:lcd屏幕锁 int deleteTag[PicTotal+1] = {0};//图片删除标记 int nowPic = 0; //当前图片索引 int nextTime = 0; //下次刷新图片时间 //初始化设备 int initDev_LCD() { while(threadLock >> 7){ //lcd线程被锁定 } threadLock=threadLock | 1 << 7; fd = open("/dev/fb0", O_RDWR); if (fd < 0) { perror("open source file failed"); return -1; } lcd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (lcd == (void *)-1) { perror("mmap failed"); return -4; } return 0; } //释放显示设备 void closeDev_LCD() { close(fd); munmap(lcd, 800 * 480 * 4); threadLock=threadLock & 0 << 7; } //初始化触摸设备 int initDev_touch() { tsfd = open("/dev/input/event0", O_RDWR); if (tsfd < 0) { perror("open chumo lcd failed"); return -1; } return 0; } //绘制背景图片 int disPic(char *path, int dx, int dy, char alpha) { if (initDev_LCD() != 0) return -1; int bmpfd = open(path, O_RDWR); if (bmpfd < 0) { perror("open source file failed"); return -2; } unsigned char head[54] = {0}; read(bmpfd, head, sizeof(head)); int width = *((int *)&head[18]); int height = *((int *)&head[22]); short bit = *((short *)&head[28]); char buf[width * height * bit / 8]; unsigned char R = 0; unsigned char G = 0; unsigned char B = 0; int lcd_buf[width * height]; read(bmpfd, buf, width * height * bit / 8); int i = 0, x = 0, y = 0; for (i = 0; i < width * height; i++) { B = buf[0 + 3 * i]; G = buf[1 + 3 * i]; R = buf[2 + 3 * i]; lcd_buf[i] = alpha << 24 | R << 16 | G << 8 | B << 0; } for (y = dy; y < height + dy; y++) { for (x = dx; x < width + dx; x++) { if (x >= 800 || y >= 480) continue; *(lcd + y * 800 + x) = lcd_buf[(height - (y - dy)) * width + x - dx]; } } close(bmpfd); closeDev_LCD(); return 0; } //清屏 void disClear(){ int x,y; initDev_LCD(); for(x=0;x<800;x++){ for(y=0;y<480;y++){ *(lcd + y*800 + x)=0xFF000000; } } closeDev_LCD(); } //绘制矩形 void drawBox(int x, int y, int width, int heigh, int border, int borderColor,int filledColor) { int nowX = 0, nowY = 0, nowB = 0; for (nowX = x + border; nowX < x + width - border; nowX++) { for (nowB = 0; nowB < border; nowB++) { nowY = y + nowB; *(lcd + (nowY)*800 + (nowX)) = borderColor; nowY = y + heigh - nowB - 1; *(lcd + (nowY)*800 + (nowX)) = borderColor; } if (filledColor != 0xEE000000) { for (nowB = 0; nowB < heigh - 2 * border; nowB++) { nowY = y + border + nowB; *(lcd + (nowY)*800 + (nowX)) = filledColor; } } } for (nowB = 0; nowB < border; nowB++) { nowX = x + nowB; for (nowY = y; nowY < y + heigh; nowY++) { *(lcd + (nowY)*800 + (nowX)) = borderColor; } nowX = x + width - nowB - 1; for (nowY = y; nowY < y + heigh; nowY++) { *(lcd + (nowY)*800 + (nowX)) = borderColor; } } } //显示触摸 void disTouch(int type, int active) { initDev_LCD(); int fillColor; if (active == 1) { fillColor = 0xFF00FF00; } else if (active == 2) { fillColor = 0xFFFFFF00; } else { fillColor = 0xFFFFFFFF; } switch (type) { case -1: drawBox(595, 61, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //按住 drawBox(595, 87, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向上 drawBox(595, 114, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向下 drawBox(595, 141, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向左 drawBox(595, 169, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向右 break; case 0: drawBox(595, 87, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向上 drawBox(595, 114, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向下 drawBox(595, 141, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向左 drawBox(595, 169, 16, 16, 2, 0xFF000000, 0xFFFFFFFF); //向右 break; case 1: drawBox(595, 61, 16, 16, 2, 0xFF000000, fillColor); //按住 break; case 2: drawBox(595, 87, 16, 16, 2, 0xFF000000, fillColor); //向上 break; case 3: drawBox(595, 114, 16, 16, 2, 0xFF000000, fillColor); //向下 break; case 4: drawBox(595, 141, 16, 16, 2, 0xFF000000, fillColor); //向左 break; case 5: drawBox(595, 169, 16, 16, 2, 0xFF000000, fillColor); //向右 break; default: break; } closeDev_LCD(); } //返回现在时间 int now() { return (int)time(&t); } //处理触摸 void *deal_touch(void *arg) { int tNowX = 0, tNowY = 0, tStartX = 0, tStartY = 0, dealSlide = 0; struct input_event ts; while (1) { read(tsfd, &ts, sizeof(ts)); dealSlide = 0; if (ts.type == EV_ABS && ts.code == ABS_X) { tNowX = ts.value; dealSlide = 1; } if (ts.type == EV_ABS && ts.code == ABS_Y) { tNowY = ts.value; dealSlide = 1; } if (ts.type == EV_KEY && ts.code == BTN_TOUCH) { if (ts.value == 1) { disTouch(1, 1); tStartX = tNowX; tStartY = tNowY; dealSlide = 1; touchEvent=0x01; touchEvent= 0x06<<24 | tNowX << 12 | tNowY; } else { disTouch(1, 0); disTouch(0, 0); if (abs(tNowX - tStartX + tNowY - tStartY) > 20) { if (abs(tNowX - tStartX) > abs(tNowY - tStartY)) { if (tNowX - tStartX > 0) { //向右滑动 disTouch(5, 2); touchEvent= 0x05<<24 | tNowX << 12 | tNowY; } else { //向左滑动 disTouch(4, 2); touchEvent= 0x04<<24 | tNowX << 12 | tNowY; } } else { if (tNowY - tStartY > 0) { //向下滑动 disTouch(3, 2); touchEvent= 0x03<<24 | tNowX << 12 | tNowY; } else { //向上滑动 disTouch(2, 2); touchEvent= 0x02<<24 | tNowX << 12 | tNowY; } } }else{ //点击事件 touchEvent= 0x01<<24 | tNowX << 12 | tNowY; } } } if (dealSlide == 1) { disTouch(0, 0); touchEvent = 0x06<<24 | tNowX << 12 | tNowY; if (abs(tNowX - tStartX) > 20) { if (tNowX - tStartX > 0) { //向右滑动 disTouch(5, 1); } else { //向左滑动 disTouch(4, 1); } } if (abs(tNowY - tStartY) > 20) { if (tNowY - tStartY > 0) { //向下滑动 disTouch(3, 1); } else { //向上滑动 disTouch(2, 1); } } } } return NULL; } //相册显示图片 void albumDisPic(int index){ char picName[20] = {0}; printf("刷新图片...\n"); sprintf(picName, "pic%d.bmp", index); disPic(picName,0,0,0xFF); } //相册更换图片 void albumChangePic(int offset){ int loop=0; do{ nowPic=nowPic+offset; if(nowPic<0){ nowPic=nowPic+PicTotal; }else if(nowPic>PicTotal-1){ nowPic=nowPic-PicTotal; } loop++; }while(deleteTag[nowPic]!=0 && loop < PicTotal); if(loop>PicTotal-1){ disClear(); disPic("nopic.bmp",300,140,0x50); nextTime = now() + 5; return; } nextTime = now() + 5; albumDisPic(nowPic); } //显示删除图标 void albumDisDeleteIcon(){ disPic("deleted.bmp",300,140,0x50); sleep(1); } int main() { int ret = 0; t = time(NULL); //初始化时间 //初始化设备 ret = initDev_LCD(); if (ret != 0) return ret; closeDev_LCD(); //初始化成功关闭 //初始化触摸设备 ret = initDev_touch(); if (ret != 0) return ret; albumDisPic(nowPic); nextTime = now() + 3; //定义下次刷新图片时间 if (pthread_create(&thread_touchDeal,NULL,deal_touch,NULL) != 0) { printf("Error: pthread_create failed.\n"); close(tsfd); return -8; } while (1) { if(touchEvent>>24!=0){ int type = touchEvent >> 24; int nowX = touchEvent <<8 >>20; int nowY = touchEvent <<20 >>20; touchEvent = 0x00000000; switch (type) { case 0x01: //点击 printf("你点击了屏幕..(%d,%d)\n",nowX,nowY); break; case 0x02: //上划 printf("你上划了屏幕..(%d,%d)\n",nowX,nowY); deleteTag[nowPic]=1;//删除图片 nextTime = now() + 3; albumDisDeleteIcon(); albumChangePic(+1); break; case 0x03: //下划 printf("你下划了屏幕..(%d,%d)\n",nowX,nowY); deleteTag[nowPic]=1;//删除图片 nextTime = now() + 3; albumDisDeleteIcon(); albumChangePic(+1); break; case 0x04: //左划 printf("你左划了屏幕..(%d,%d)\n",nowX,nowY); albumChangePic(-1); break; case 0x05: //右划 printf("你右划了屏幕..(%d,%d)\n",nowX,nowY); albumChangePic(+1); break; default: printf("屏幕事件%x..(%d,%d)\n",type,nowX,nowY); break; } } if (now() > nextTime) { printf("刷新图片...\n"); albumChangePic(+1); } } close(tsfd); return 0; }
注释比较精简,见谅。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。