c语言将bmp图片转换成c语言数组

发布于:2025-08-18 ⋅ 阅读:(15) ⋅ 点赞:(0)

功能类似:
在这里插入图片描述
主要针对超高分辨率图片。

直接上代码:

#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;
}

实现效果:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到