int (*lcd)[800] = NULL; //打开帧缓存设备文件 //映射内存 void lcd_lnit(){ int lcd_fd = open("/dev/fb0",O_RDWR); //系统io可以访问任何类型文件 if(lcd_fd < 0){ perror("打开lcd设备文件失败"); return ; } lcd = mmap(NULL,800 * 480 * 4,PROT_READ | PROT_WRITE,MAP_SHARED,lcd_fd,0); if(lcd == NULL){ perror("映射失败"); return ; } close(lcd_fd); } //打开bmp文件,把图片放到缓存区 void bmp_init(char *bmp_path){ int bmp_fd = open("./1.bmp",O_RDWR); if(bmp_fd <0){perror("打开图片失败");return ;} struct bitmap_header head; read(bmp_fd,&head,14); struct bitmap_info info; read(bmp_fd,&info,40); char rgb[800*480*3]; read(bmp_fd,&rgb,sizeof(rgb)); char argb[800*480*4]; for(int i = 0; i < 480 * 800 ;i++){ argb[0+i*4] = rgb[0+i*3]; argb[1+i*4] = rgb[1+i*3]; argb[2+i*4] = rgb[2+i*3]; argb[3+i*4] = 0; //透明度 } //转换成二维数组 int (*p)[800] = (void*)argb; for(int y = 0; y < 480; y++){ for(int x = 0; x < 800; x++){ lcd[y][x] = p[479-y][x]; } } close(bmp_fd); } //插入双向链表 struct node{ char path[1024]; struct node *next; struct node *prev; }; void insert_node(struct node *head,char *path){ //新建结点 struct node *xnew = malloc(sizeof(struct node)); //初始化数据域 strcpy(xnew -> path ,path); //初始化地址域 xnew -> next = xnew; xnew -> prev = xnew; //插入节点到链表中 xnew -> prev = head -> prev; xnew -> next = head; head -> prev -> next = xnew; head -> next = xnew; } //打开触摸屏设备文件 void event_init(struct node *pos){ int fd = open("/dev/input/event0",O_RDWR); if(fd < 0){perror("打开触摸屏设备文件失败");return ;} int tx,ty; int touch_x,touch_y; while(1){ struct input_event ev; read(fd,&ev,sizeof(ev)); if(ev.type == EV_SYN){ // printf("-----------SYN------------\n"); } if(ev.type == EV_ABS && ev.code == ABS_X){ // printf("x = %d\n",ev.value); //ev.value*800/1024 tx = ev.value; } if(ev.type == EV_ABS && ev.code == ABS_Y){ // printf("y = %d\n",ev.value); //ev.value*480/600 ty = ev.value; } if(ev.type == EV_KEY && ev.code == BTN_TOUCH){ if(ev.value > 0){ printf("按下x =%d,y=%d\n",tx,ty); touch_x = tx; touch_y = ty; } else{ printf("松开x =%d,y=%d\n",tx,ty); if(touch_x - tx < -100) {printf("向右滑动\n"); if(strcmp(pos -> path, "NULL") != 0){ pos = pos -> next; bmp_init(pos -> path); } } else if(touch_x -tx > 100) { printf("向左滑动\n"); if(strcmp(pos -> path, "NULL") != 0){ pos = pos -> prev; bmp_init(pos -> path); } } else if(touch_y - ty < -100) {printf("向下滑动\n");} else if(touch_y -ty > 100) {printf("向上滑动\n");} } } } close(fd); } //获取信息 //实现左右滑动显示坐标,根据向左划还是向右滑动切换图片 int main(){ //创建头节点 struct node *head = malloc(sizeof(struct node)); strcpy(head -> path,"NULL"); head -> next = head; head -> prev = head; //插入结点 insert_node(head,"dihuangxia1.bmp"); insert_node(head,"mouyitian.bmp"); lcd_lnit(); struct node *pos =head; event_init(pos); }为什么滑动之后没有显示图片
时间: 2025-06-12 11:12:16 浏览: 18
<think>好的,我现在需要分析用户提供的代码,找出为什么滑动后图片没有显示的原因。首先,用户提到他们使用了一个双向链表来管理图片路径,并通过触摸事件切换图片,但滑动后没有显示新图片。
首先,我应该通读代码,理解各个部分的功能。代码主要分为几个部分:LCD初始化、BMP图片加载、双向链表的插入、触摸屏事件处理以及主函数。问题可能出在触摸事件处理或图片加载过程中。
在触摸事件处理函数event_init中,当检测到左右滑动时,会改变pos指针的位置,然后调用bmp_init(pos->path)来加载新图片。但问题可能在于,pos指针的传递方式是否正确。因为C语言中函数参数是值传递,如果在event_init函数中修改了pos,这个修改不会反映到主函数的pos变量中。也就是说,尽管在event_init内部pos被改变,但主函数中的pos仍然指向原来的节点,导致后续切换无效。
接下来检查bmp_init函数。该函数负责读取BMP文件并将其显示到LCD上。需要确认是否正确处理了像素格式的转换,尤其是从RGB到ARGB的转换,以及是否正确将像素数据写入LCD的内存映射区域。此外,BMP文件的行顺序通常是倒置的,代码中使用479-y来翻转图像,这部分是否正确。
另外,检查链表插入函数insert_node。每插入一个新节点,是否正确链接了前后指针。例如,插入到head的前面还是后面,可能需要确认链表的连接顺序是否正确,避免形成环状结构导致遍历时无法正确访问所有节点。
还有可能的问题是,在event_init函数中,每次滑动时是否确实调用了bmp_init,并且传入的路径是否正确。例如,如果链表中节点的path字段未正确设置,或者路径字符串有误,可能导致加载失败。此外,打开BMP文件时使用的是固定路径"./1.bmp",而不是传入的bmp_path参数,这会导致始终加载同一张图片,无法切换。
最后,检查内存映射和LCD初始化的部分是否正确,确保lcd指针有效,并且写入的数据能够正确反映到屏幕上。如果映射失败或指针使用不当,可能导致图像无法显示。
总结可能的问题点:
1. event_init函数中的pos指针传递方式错误,导致主函数中的pos未被更新。
2. bmp_init函数中硬编码了BMP路径,未使用传入的参数。
3. 链表插入或遍历错误,导致节点路径不正确。
4. 图像数据转换或写入LCD内存时出错。</think>这段代码存在多个问题导致滑动后无法显示图片,以下是逐步分析:
$$1.\ 指针传递问题$$
在`event_init`函数中,修改的是形参`pos`的指向:
```c
void event_init(struct node *pos){ //形参是局部指针变量
...
pos = pos->next; //修改的只是函数内部的副本
}
```
主函数中的`pos`指针并未改变。应采用**二级指针**传递:
```c
void event_init(struct node **pos){ //改为二级指针
...
*pos = (*pos)->next; //通过解引用修改外部指针
}
// 调用时传递指针地址
event_init(&pos);
```
$$2.\ 路径加载问题$$
`bmp_init`函数存在硬编码路径:
```c
int bmp_fd = open("./1.bmp",O_RDWR); // 应该使用传入的bmp_path参数
```
应修改为:
```c
int bmp_fd = open(bmp_path, O_RDWR); // 使用传入的路径参数
```
$$3.\ 链表操作问题$$
插入节点时链接错误:
```c
head->prev->next = xnew;
head->next = xnew; // 错误!应改为 head->prev = xnew
```
正确顺序应为:
```c
xnew->prev = head->prev;
xnew->next = head;
head->prev->next = xnew;
head->prev = xnew; // 修正这一行
```
$$4.\ 坐标映射问题$$
触摸事件坐标未做屏幕适配:
```c
tx = ev.value; // 原始值是0-1024范围
ty = ev.value; // 原始值是0-600范围
```
应转换为屏幕坐标:
```c
tx = ev.value * 800 / 1024; // 适配800宽度
ty = ev.value * 480 / 600; // 适配480高度
```
$$5.\ 内存对齐问题$$
BMP文件头读取时:
```c
struct bitmap_header head;
read(bmp_fd,&head,14); // 实际BMP文件头是14字节
```
但标准BMP头结构体应为:
```c
#pragma pack(push, 1) // 确保1字节对齐
struct bitmap_header {
uint16_t type; // 2字节
uint32_t size; // 4字节
uint16_t reserved1; // 2
uint16_t reserved2; // 2
uint32_t offset; // 4
}; // 共14字节
#pragma pack(pop)
```
$$6.\ 图像方向问题$$
BMP图像存储是**从下到上**,但代码中使用:
```c
lcd[y][x] = p[479-y][x]; // 可能双重反转
```
应改为:
```c
lcd[y][x] = p[y][x]; // 根据实际文件方向调整
```
建议按以下顺序调试:
1. 验证链表操作是否正确(打印节点路径)
2. 检查`bmp_init`是否成功打开文件
3. 使用`printf`输出滑动后的pos->path
4. 添加错误处理:
```c
if(access(bmp_path, F_OK) == -1) {
printf("%s not exist\n", bmp_path);
return;
}
```
5. 使用`perror`检查所有系统调用返回值
修正这些问题后,滑动切换功能应该可以正常工作。关键是要确保指针传递正确、路径加载准确、坐标映射合理这三个核心问题得到解决。
阅读全文
相关推荐













