网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > C语言 >

24位色深bmp图片显示lcd屏幕上

时间:2025-08-07 22:02

人气:

作者:admin

标签:

导读:设计一个将24位色深的bmp图片显示到lcd屏幕上,可移植,该程序自己写过之后,又经过了ai的完善和修复后,自己又再次添加一些语句注释 /**********************************************************...

设计一个将24位色深的bmp图片显示到lcd屏幕上,可移植,该程序自己写过之后,又经过了ai的完善和修复后,自己又再次添加一些语句注释



/****************************************************************************
 *
 * file name: 2025-07-30_filecopy.c
 * author   : 15515376695@163.com
 * date     : 2025-07-30
 * function : 该程序实现BMP图片信息的读取,且显示在lcd屏幕上
 * note     : None
 * CopyRight (c)   2025  15515376695@163.com   Right Reseverd
 *
 ****************************************************************************/



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>

#pragma pack(1)
// BMP文件头(14字节)
typedef struct {
    unsigned short bfType;       // 必须为0x4D42("BM"标识)
    unsigned int   bfSize;       // 文件总大小(字节)
    unsigned short bfReserved1;  // 保留字段,0
    unsigned short bfReserved2;  // 保留字段,0
    unsigned int   bfOffBits;    // 像素数据偏移量(从文件头开始)
} BITMAPFILEHEADER;

// BMP信息头(40字节,Windows格式)
typedef struct {
    unsigned int biSize;         // 信息头大小(40字节)
    int          biWidth;        // 图像宽度(像素)
    int          biHeight;       // 图像高度(像素,负数表示从上到下存储)
    unsigned short biPlanes;     // 必须为1
    unsigned short biBitCount;   // 色深(每像素位数)
    unsigned int   biCompression;// 压缩方式(0表示不压缩)
    unsigned int   biSizeImage;  // 像素数据大小(字节,0表示不压缩时可忽略)
    int            biXPelsPerMeter; // 水平分辨率(像素/米)
    int            biYPelsPerMeter; // 垂直分辨率(像素/米)
    unsigned int   biClrUsed;    // 使用的颜色数(0表示全部)
    unsigned int   biClrImportant; // 重要颜色数(0表示全部)
} BITMAPINFOHEADER;
#pragma pack()


int main(int argc, char const *argv[]) {
    // 1. 检查命令行参数
    if (argc != 2) {
        fprintf(stderr, "用法: %s <24位无压缩BMP文件路径>\n", argv[0]);
        return -1;
    }

    // 2. 打开BMP文件并验证合法性
    FILE *bmp_fp = fopen(argv[1], "rb");
    if (bmp_fp == NULL) {
        perror("无法打开BMP文件");
        return -1;
    }

    // 3. 读取并验证BMP文件头
    BITMAPFILEHEADER file_header;
    if (fread(&file_header, sizeof(BITMAPFILEHEADER), 1, bmp_fp) != 1) {
        perror("读取BMP文件头失败");
        fclose(bmp_fp);
        return -1;
    }
    if (file_header.bfType != 0x4D42) { // "BM"的十六进制表示
        fprintf(stderr, "错误:不是BMP文件(标识不符)\n");
        fclose(bmp_fp);
        return -1;
    }

    // 4. 读取并验证BMP信息头
    BITMAPINFOHEADER info_header;
    if (fread(&info_header, sizeof(BITMAPINFOHEADER), 1, bmp_fp) != 1) {
        perror("读取BMP信息头失败");
        fclose(bmp_fp);
        return -1;
    }
    // 仅支持24位色、不压缩的BMP
    if (info_header.biBitCount != 24) {
        fprintf(stderr, "错误:仅支持24位色BMP(当前色深:%d位)\n", info_header.biBitCount);
        fclose(bmp_fp);
        return -1;
    }
    if (info_header.biCompression != 0) {
        fprintf(stderr, "错误:仅支持无压缩BMP(当前压缩方式:%d)\n", info_header.biCompression);
        fclose(bmp_fp);
        return -1;
    }

    // 5. 获取BMP宽高(处理高度可能为负数的情况)
    int bmp_width = info_header.biWidth;
    int bmp_height = abs(info_header.biHeight); // 取绝对值(高度符号表示存储方向)
    printf("BMP信息:宽=%dpx,高=%dpx,像素数据偏移量=%d字节\n", 
           bmp_width, bmp_height, file_header.bfOffBits);

    // 6. 计算BMP每行实际字节数(必须是4的倍数,含填充字节)
    int line_bytes = (bmp_width * 3 + 3) / 4 * 4; // 向上取4的倍数
    int pixel_data_size = line_bytes * bmp_height; // 总像素数据大小(含填充)

    // 7. 分配内存存储像素数据(堆内存,避免栈溢出)
    unsigned char *bmp_pixels = malloc(pixel_data_size);//pixels是像素的意思
    if (bmp_pixels == NULL) {
        perror("内存分配失败");
        fclose(bmp_fp);
        return -1;
    }

    // 8. 定位到像素数据位置并读取
    if (fseek(bmp_fp, file_header.bfOffBits, SEEK_SET) != 0) {
        perror("定位到像素数据失败");
        free(bmp_pixels);
        fclose(bmp_fp);
        return -1;
    }
    if (fread(bmp_pixels, 1, pixel_data_size, bmp_fp) != pixel_data_size) {
        perror("读取像素数据失败");
        free(bmp_pixels);
        fclose(bmp_fp);
        return -1;
    }
    fclose(bmp_fp); // 像素数据已读取,关闭BMP文件

    // 9. 打开LCD设备(framebuffer)
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd == -1) {
        perror("无法打开LCD设备(/dev/fb0)");
        free(bmp_pixels);
        return -1;
    }

    // 10. 内存映射LCD(假设LCD分辨率与BMP一致,实际可通过ioctl获取)
    int lcd_size = bmp_width * bmp_height * 4; // 每个像素4字节(ARGB)
    int *lcd_mp = (int *)mmap(NULL, lcd_size, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    if (lcd_mp == MAP_FAILED) {
        perror("LCD内存映射失败");
        close(lcd_fd);
        free(bmp_pixels);
        return -1;
    }

    // 11. 像素转换与显示(处理BMP存储方向)
    for (int y = 0; y < bmp_height; y++) {
        // BMP高度为正数时,像素数据从上到下存储的是图像的底部到顶部,需翻转y轴
        int bmp_y = (info_header.biHeight > 0) ? (bmp_height - 1 - y) : y;
                  //条件 ? 表达式1 : 表达式2      //实现了行索引的翻转
                 //意思是:如果 “条件” 为真(非 0),就返回 “表达式 1” 的结果;否则返回 “表达式 2” 的结果。
        
        for (int x = 0; x < bmp_width; x++) {
            // 计算BMP每个像素在内存中所对应的位置(跳过每行填充字节)
            int bmp_idx = bmp_y * line_bytes + x * 3;
            // BMP像素格式:BGR,转换为LCD的ARGB(Alpha=0xFF表示不透明)
            unsigned char b = bmp_pixels[bmp_idx];//blue
            unsigned char g = bmp_pixels[bmp_idx + 1];//green
            unsigned char r = bmp_pixels[bmp_idx + 2];//red
            //进行偏移成argb的色彩与lcd对应
            int argb = 0xFF000000 | (r << 16) | (g << 8) | b; // 0xFF为Alpha通道(不透明)
                    
            // 写入LCD对应位置
            lcd_mp[y * bmp_width + x] = argb;
        }
    }


    // 12. 清理资源
    munmap(lcd_mp, lcd_size);
    close(lcd_fd);
    free(bmp_pixels);
    printf("图像显示完成\n");
    return 0;
}


温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信