m0NESY. 2024-05-26 01:30 采纳率: 55.6%
浏览 129
已结题

打不开bmp文件,运行到open(bmp)就结束了

用虚拟机和crt做的。
内容是将bmp显示到lcd板子上,
打开开发版成功了,就是打不开bmp,怎么解决


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
int *plcd = NULL;
int init_lcd(){
    int fd = open("/dev/fb0",O_RDWR);//可读可写打开显示屏
    if(fd < 0){
        perror("fail to open");
        return -1;
    } 
    plcd = (int*)mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
                                    //读写权限    映射标志
    if(plcd == MAP_FAILED){//失败返回MAP_FALED,同时errno被设置 
        perror("mmap error");
        return -1;
    } 
    return fd;
}
void close_lcd(int fd){
    munmap(plcd,800*480*4);//解映射
    close(fd); 
}
/*
display_point:显示一个点
x:像素点的横坐标
y:像素点的纵坐标
color:要显示的颜色
*/
void display_point(int x,int y,int color){
    if(x>=0 && x<800 && y>=0 && y<480){//像素点在开发板上有效 
        *(plcd + 800*y+x) = color;
    }
}
/*
    功能:解析bmp图片并且居中显示
    参数:
        @bmpname:图片名
        @x0:从哪列开始
        @y0:从哪行开始
    返回值:0是没问题
    -1,-2,-3对应的出错
*/
int display_bmp(const char *bmpname,int x0,int y0)
{
    //1、打开图片
    int fd = open(bmpname,O_RDONLY);
    if(fd < 0){
        printf("fail to open bmp");
        return -1;
    }
    //2、判断是不是bmp图片
    char buf[2]={0};
    read(fd,buf,2);
    if(buf[0] != 'B' || buf[1] != 'M'){
        printf("Not a bmp file\n");
        close(fd);
        return -2;
    }
    //3、获取图片属性 宽、高、色深
    int width,height,depth;
    lseek(fd,0x12,SEEK_SET);
    read(fd,&width,4);
    read(fd,&height,4);
    lseek(fd,0x1C,SEEK_SET); 
    read(fd,&depth,2);
    if(!(depth == 24 || depth == 32))
    {
        printf("NOT depth\n");
        close(fd);
        return -3;
    }
    printf("bmpname : %s , width = %d , height = %d , depth = %d\n",bmpname,width,height,depth);
    //4、获取像素数组
    int size = width*height*depth/8;
    char *pbuf = (char *)malloc(size);
    lseek(fd,54,SEEK_SET);
    read(fd,pbuf,size);
    //5、显示这个图片 就是一个一个像素点显示
    //进行显示
    for(int x = 0;x < height;x++){
        for(int y = 0;y < width;y++){
            char b = *(pbuf + x * width * depth / 8 + y * depth / 8);
            char g = *(pbuf + x * width * depth / 8 + y * depth / 8 + 1);
            char r = *(pbuf + x * width * depth / 8 + y * depth / 8 + 2);
            unsigned int color = r << 16 | g << 8 | b;
            display_point(x0+x,y0+y,color);
        }
    }
    free(pbuf);
    close(fd);
    return 0;
}
int main()
{
    int fd = init_lcd();
    char bmpname[] = "lufei.bmp";
    display_bmp(bmpname,0,0);
    close_lcd(fd);
}

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-05-26 01:30
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    根据你提供的代码和遇到的问题,我将尝试为你提供一些可能的解决方案和建议。

    1. 为什么程序在open(bmpname, O_RDONLY)这一行停止运行?

    程序在open(bmpname, O_RDONLY)停止运行可能是因为以下几个原因:

    • 文件路径错误:确保bmpname变量中的文件路径是正确的,并且该文件确实存在于该路径下。
    • 文件权限问题:检查程序是否有权限读取该bmp文件。可以使用ls -l命令查看文件权限,并确保程序有读取权限。
    • 文件不存在:确认文件确实存在,并且没有被其他程序占用。
    • 程序逻辑错误:如果open调用失败,程序应该打印错误信息并返回错误代码,而不是停止运行。检查是否有逻辑错误导致程序在错误发生时没有正确处理。

    2. 如何确保bmp文件被正确打开并读取?

    • 检查文件路径:确保文件路径是正确的,可以使用绝对路径或相对于程序运行目录的相对路径。
    • 错误处理:在open调用后添加错误处理逻辑,如果文件无法打开,打印错误信息并退出程序。
    • 使用access函数:在尝试打开文件之前,使用access(bmpname, R_OK)检查文件是否存在且可读。

    3. 如何确保bmp文件的格式和属性被正确解析?

    • 检查文件头:确保文件头的前两个字节是'B'和'M',这是BMP文件的标志。
    • 读取文件属性:根据BMP文件的格式规范,读取宽度、高度和颜色深度等属性,并确保它们是预期的值。
    • 使用结构体:定义一个结构体来存储BMP文件的属性,这样可以使代码更清晰。

    4. 如何将解析后的bmp图片数据正确显示在LCD上?

    • 像素数据转换:确保像素数据从BMP格式转换为LCD支持的格式。BMP文件通常是BGR格式,而LCD可能需要RGB格式。
    • 坐标转换:如果需要将图片居中显示,需要计算x0和y0的值,使得图片在LCD上居中。
    • 逐像素绘制:使用display_point函数逐像素绘制图片。

    代码实现建议:

    // 在display_bmp函数中添加错误处理
    int fd = open(bmpname, O_RDONLY);
    if (fd < 0) {
        perror("Unable to open BMP file");
        return -1;
    }
    
    // 其他代码...
    
    // 在main函数中添加错误处理
    int result = display_bmp(bmpname, 0, 0);
    if (result != 0) {
        fprintf(stderr, "Error displaying BMP file: %d\n", result);
        return result;
    }
    

    参考资料:

    希望这些建议能帮助你解决问题。如果问题仍然存在,请提供更多的错误信息或日志,以便进一步分析。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月26日
  • 创建了问题 5月26日