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; }
关键细节解释
- 结构体对齐:用
#pragma pack禁用默认对齐是因为BMP头要求字段紧凑排列,默认的结构体对齐会导致字段间出现空白字节,破坏BMP格式。 - biHeight的正负:正数表示像素从图像左下角开始存储,负数则从左上角开始,代码里用正数所以row1对应图像最下方的像素。
- 字节对齐:BMP要求每行字节数是4的倍数,用
((width * bits_per_pixel) +31)/32 *4可以自动计算出需要的对齐后字节数,不足的部分用0填充。 - 像素顺序:BMP存储像素是BGR顺序,不是我们习惯的RGB,所以红色要写成
0x00,0x00,0xFF,这点很容易踩坑。
编译运行
在Linux下直接用gcc编译:
gcc bmp_create.c -o bmp_create ./bmp_create
运行后会生成2x2.bmp,用系统自带的图像查看器就能看到2x2的四色方块。
内容的提问来源于stack exchange,提问作者elanonrigby
相关产品推荐
相关产品推荐

