You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下无外部库用C创建2x2位图的技术求助及示例需求

没问题!我来给你一个带详细注释的C语言实现,同时把BMP头的参数作用讲清楚——完全不需要任何外部库,纯标准C就能在Linux下搞定2x2的Bitmap图像。

用C语言创建2x2 Bitmap图像(Linux环境,无外部库)

先搞懂BMP的核心结构

Bitmap文件主要由三部分组成:

  • 文件头(BITMAPFILEHEADER):告诉系统这是BMP文件,以及文件总大小、像素数据的起始位置
  • 信息头(BITMAPINFOHEADER):存储图像的宽高、颜色深度、压缩方式等关键信息
  • 像素数据:按BGR顺序存储每个像素的颜色值(注意不是RGB!),而且每行的字节数必须对齐到4的倍数(BMP的硬性要求)

带注释的完整代码

#include <stdio.h>
#include <stdint.h>

// 禁用结构体默认对齐,保证BMP头字段紧凑排列(BMP格式要求严格的字节顺序)
#pragma pack(push, 1)
// BMP文件头结构体
typedef struct {
    uint16_t bfType;        // 必须为0x4D42(ASCII的'BM'),标识这是BMP文件
    uint32_t bfSize;        // 整个BMP文件的总字节数
    uint16_t bfReserved1;   // 保留字段,固定为0
    uint16_t bfReserved2;   // 保留字段,固定为0
    uint32_t bfOffBits;     // 从文件开头到像素数据的偏移字节数
} BITMAPFILEHEADER;

// BMP信息头结构体
typedef struct {
    uint32_t biSize;        // 本结构体的大小,固定为40字节
    int32_t  biWidth;       // 图像宽度(像素数)
    int32_t  biHeight;      // 图像高度(像素数,正数表示像素从下到上存储)
    uint16_t biPlanes;      // 颜色平面数,必须为1
    uint16_t biBitCount;    // 每个像素的位数,这里用24位真彩色(3字节/像素)
    uint32_t biCompression; // 压缩方式,0表示无压缩(BI_RGB)
    uint32_t biSizeImage;   // 像素数据的总字节数(含对齐填充)
    int32_t  biXPelsPerMeter; // 水平分辨率(像素/米),可设为0
    int32_t  biYPelsPerMeter; // 垂直分辨率(像素/米),可设为0
    uint32_t biClrUsed;     // 使用的颜色数,24位真彩色设为0
    uint32_t biClrImportant;// 重要颜色数,设为0即可
} BITMAPINFOHEADER;
#pragma pack(pop) // 恢复默认结构体对齐

int main() {
    // 定义图像参数
    const int width = 2;
    const int height = 2;
    const int bits_per_pixel = 24;

    // 计算每行字节数(必须对齐到4的倍数)
    int bytes_per_row = ((width * bits_per_pixel) + 31) / 32 * 4;
    int pixel_data_size = bytes_per_row * height;

    // 初始化文件头和信息头
    BITMAPFILEHEADER file_header = {0};
    BITMAPINFOHEADER info_header = {0};

    // 填充文件头
    file_header.bfType = 0x4D42; // 'BM'的十六进制表示
    file_header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pixel_data_size;
    file_header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // 填充信息头
    info_header.biSize = sizeof(BITMAPINFOHEADER);
    info_header.biWidth = width;
    info_header.biHeight = height; // 正数表示像素从图像左下角开始存储
    info_header.biPlanes = 1;
    info_header.biBitCount = bits_per_pixel;
    info_header.biCompression = 0;
    info_header.biSizeImage = pixel_data_size;

    // 打开文件(二进制写入模式)
    FILE* bmp_file = fopen("2x2.bmp", "wb");
    if (!bmp_file) {
        perror("Failed to open file");
        return 1;
    }

    // 写入文件头和信息头
    fwrite(&file_header, sizeof(BITMAPFILEHEADER), 1, bmp_file);
    fwrite(&info_header, sizeof(BITMAPINFOHEADER), 1, bmp_file);

    // 准备像素数据:BMP存储顺序为BGR,每行末尾补对齐字节
    // 第一行对应图像最下方的两个像素:红、绿
    uint8_t row1[] = {
        0x00, 0x00, 0xFF, // 红色:B=0, G=0, R=255
        0x00, 0xFF, 0x00, // 绿色:B=0, G=255, R=0
        0x00, 0x00        // 对齐补2字节,凑够8字节(4的倍数)
    };
    // 第二行对应图像最上方的两个像素:蓝、白
    uint8_t row2[] = {
        0xFF, 0x00, 0x00, // 蓝色:B=255, G=0, R=0
        0xFF, 0xFF, 0xFF, // 白色:B=255, G=255, R=255
        0x00, 0x00        // 对齐补2字节
    };

    // 写入像素数据
    fwrite(row1, sizeof(row1), 1, bmp_file);
    fwrite(row2, sizeof(row2), 1, bmp_file);

    // 关闭文件
    fclose(bmp_file);

    printf("2x2.bmp created successfully!\n");
    return 0;
}

关键细节解释

  1. 结构体对齐:用#pragma pack禁用默认对齐是因为BMP头要求字段紧凑排列,默认的结构体对齐会导致字段间出现空白字节,破坏BMP格式。
  2. biHeight的正负:正数表示像素从图像左下角开始存储,负数则从左上角开始,代码里用正数所以row1对应图像最下方的像素。
  3. 字节对齐:BMP要求每行字节数是4的倍数,用((width * bits_per_pixel) +31)/32 *4可以自动计算出需要的对齐后字节数,不足的部分用0填充。
  4. 像素顺序:BMP存储像素是BGR顺序,不是我们习惯的RGB,所以红色要写成0x00,0x00,0xFF,这点很容易踩坑。

编译运行

在Linux下直接用gcc编译:

gcc bmp_create.c -o bmp_create
./bmp_create

运行后会生成2x2.bmp,用系统自带的图像查看器就能看到2x2的四色方块。

内容的提问来源于stack exchange,提问作者elanonrigby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:38:28