功能类似:
主要针对超高分辨率图片。
直接上代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#pragma pack(push, 1)
typedef struct {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
} BITMAPFILEHEADER;
typedef struct {
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} BITMAPINFOHEADER;
#pragma pack(pop)
void saveBMPToCArray(const char* bmpFilename, const char* outputFilename) {
FILE* bmpFile = fopen(bmpFilename, "rb");
if (!bmpFile) {
printf("Error opening BMP file\n");
return;
}
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
// 读取文件头和信息头
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, bmpFile);
fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, bmpFile);
// 检查是否是BMP文件
if (fileHeader.bfType != 0x4D42) {
printf("Not a BMP file\n");
fclose(bmpFile);
return;
}
// 检查位深度是否为24位
if (infoHeader.biBitCount != 24) {
printf("Only 24-bit BMP files are supported\n");
fclose(bmpFile);
return;
}
int width = infoHeader.biWidth;
int height = abs(infoHeader.biHeight); // 处理可能为负的高度
int dataSize = width * height * 3; // 24位色,每个像素3字节
// 分配内存存储图像数据
unsigned char* imageData = (unsigned char*)malloc(dataSize);
if (!imageData) {
printf("Memory allocation failed\n");
fclose(bmpFile);
return;
}
// 计算每行字节数并考虑对齐
int rowSize = ((width * 3 + 3) / 4) * 4;
int padding = rowSize - width * 3;
// 读取图像数据
fseek(bmpFile, fileHeader.bfOffBits, SEEK_SET);
for (int y = 0; y < height; y++) {
fread(imageData + y * width * 3, width * 3, 1, bmpFile);
fseek(bmpFile, padding, SEEK_CUR); // 跳过填充字节
}
fclose(bmpFile);
// 创建输出文件
FILE* outFile = fopen(outputFilename, "w");
if (!outFile) {
printf("Error creating output file\n");
free(imageData);
return;
}
// 写入数组声明
fprintf(outFile, "const unsigned char gImage_%s_%d_%d[%d] = { /* 0X10,0X10,0X00,0X00,0X%02X,0X00,0X%02X,0X00, */\n",
outputFilename, width, height, dataSize, width & 0xFF, height & 0xFF);
// 写入图像数据
for (int i = 0; i < dataSize; i++) {
if (i % 16 == 0) {
if (i != 0) fprintf(outFile, "\n");
fprintf(outFile, " ");
}
fprintf(outFile, "0X%02X", imageData[i]);
if (i != dataSize - 1) fprintf(outFile, ",");
}
fprintf(outFile, "\n};\n");
fclose(outFile);
free(imageData);
printf("Conversion complete. Saved to %s\n", outputFilename);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("Usage: %s <input.bmp> <output.c>\n", argv[0]);
return 1;
}
saveBMPToCArray(argv[1], argv[2]);
return 0;
}
使用说明:
将上面的代码保存为 bmp2c.c
编译程序:gcc bmp2c.c -o bmp2c
运行程序:./bmp2c input.bmp output.c
程序功能:
自动读取BMP文件的宽度和高度
支持24位色的BMP文件
生成包含图像数据的C数组
数组名称格式为 gImage_文件名_宽度_高度
注释中包含图像的尺寸信息
翻转180度 数据
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#pragma pack(push, 1)
typedef struct {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
} BITMAPFILEHEADER;
typedef struct {
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} BITMAPINFOHEADER;
#pragma pack(pop)
void saveBMPToCArray(const char* bmpFilename, const char* outputFilename) {
FILE* bmpFile = fopen(bmpFilename, "rb");
if (!bmpFile) {
printf("Error opening BMP file\n");
return;
}
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, bmpFile);
fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, bmpFile);
if (fileHeader.bfType != 0x4D42) {
printf("Not a BMP file\n");
fclose(bmpFile);
return;
}
if (infoHeader.biBitCount != 24) {
printf("Only 24-bit BMP files are supported\n");
fclose(bmpFile);
return;
}
int width = infoHeader.biWidth;
int height = abs(infoHeader.biHeight);
int dataSize = width * height * 3;
int rowSize = ((width * 3 + 3) / 4) * 4;
int padding = rowSize - width * 3;
unsigned char* imageData = (unsigned char*)malloc(dataSize);
if (!imageData) {
printf("Memory allocation failed\n");
fclose(bmpFile);
return;
}
// 读取图像数据并同时进行180度翻转
fseek(bmpFile, fileHeader.bfOffBits, SEEK_SET);
for (int y = height - 1; y >= 0; y--) {
unsigned char* rowStart = imageData + y * width * 3;
for (int x = width - 1; x >= 0; x--) {
unsigned char* pixel = rowStart + x * 3;
fread(pixel, 3, 1, bmpFile);
}
fseek(bmpFile, padding, SEEK_CUR);
}
fclose(bmpFile);
FILE* outFile = fopen(outputFilename, "w");
if (!outFile) {
printf("Error creating output file\n");
free(imageData);
return;
}
// 提取基本文件名(不含路径和扩展名)
char baseName[256];
const char* p = bmpFilename;
const char* lastSlash = p;
while (*p) {
if (*p == '/' || *p == '\\') lastSlash = p + 1;
p++;
}
const char* dot = strrchr(lastSlash, '.');
int len = dot ? (int)(dot - lastSlash) : (int)(p - lastSlash);
strncpy(baseName, lastSlash, len);
baseName[len] = '\0';
fprintf(outFile, "const unsigned char gImage_%s_%d_%d[%d] = { /* 0X10,0X10,0X00,0X00,0X%02X,0X00,0X%02X,0X00, */\n",
baseName, width, height, dataSize, width & 0xFF, height & 0xFF);
for (int i = 0; i < dataSize; i++) {
if (i % 16 == 0) {
if (i != 0) fprintf(outFile, "\n");
fprintf(outFile, " ");
}
fprintf(outFile, "0X%02X", imageData[i]);
if (i != dataSize - 1) fprintf(outFile, ",");
}
fprintf(outFile, "\n};\n");
fclose(outFile);
free(imageData);
printf("Conversion complete. Saved to %s\n", outputFilename);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("Usage: %s <input.bmp> <output.c>\n", argv[0]);
return 1;
}
saveBMPToCArray(argv[1], argv[2]);
return 0;
}
实现效果: