在没有其他库的情况下用纯 c/c 编写 BMP 图像

新手上路,请多包涵

在我的算法中,我需要创建一个信息输出。我需要将布尔矩阵写入 bmp 文件。它必须是单色图像,如果此类元素上的矩阵为真,则像素为白色。主要问题是 bmp 标头以及如何编写。

原文由 den bardadym 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 657
2 个回答

无需使用任何其他库,您就可以查看 BMP 文件格式。我过去已经实现了它,它可以在没有太多工作的情况下完成。

位图文件结构

每个位图文件包含一个位图文件头、一个位图信息头、一个颜色表和一个定义位图位的字节数组。该文件具有以下形式:

位图文件头 bmfh;

BITMAPINFOHEADER bmih;

RGBQUAD aColors[];

字节 aBitmapBits[];

…查看文件格式了解更多详情

原文由 Brian R. Bondy 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是一个简单的 c++ bmp 图像文件类。

 class bmp_img {
public:
    constexpr static int header_size = 14;
    constexpr static int info_header_size = 40;
    constexpr static size_t bytes_per_pixel = 3;

    bmp_img(size_t width, size_t height) :
        image_px_width{ width }, image_px_height{ height }, row_width{ image_px_width * bytes_per_pixel },
        row_padding{ (4 - row_width % 4) % 4 }, row_stride{ row_width + row_padding }, file_size{ header_size + info_header_size + (image_px_height * row_stride) },
        image(image_px_height, std::vector<unsigned char>(row_width))
    {
        //header file type
        file_header[0] = 'B';
        file_header[1] = 'M';

        //header file size info
        file_header[2] = static_cast<unsigned char>(file_size);
        file_header[3] = static_cast<unsigned char>(file_size >> 8);
        file_header[4] = static_cast<unsigned char>(file_size >> 16);
        file_header[5] = static_cast<unsigned char>(file_size >> 24);

        //header offset to pixel data
        file_header[10] = header_size + info_header_size;

        //info header size
        info_header[0] = info_header_size;

        //info header image width
        info_header[4] = static_cast<unsigned char>(image_px_width);
        info_header[5] = static_cast<unsigned char>(image_px_width >> 8);
        info_header[6] = static_cast<unsigned char>(image_px_width >> 16);
        info_header[7] = static_cast<unsigned char>(image_px_width >> 24);

        //info header image height
        info_header[8] = static_cast<unsigned char>(image_px_height);
        info_header[9] = static_cast<unsigned char>(image_px_height >> 8);
        info_header[10] = static_cast<unsigned char>(image_px_height >> 16);
        info_header[11] = static_cast<unsigned char>(image_px_height >> 24);

        //info header planes
        info_header[12] = 1;

        //info header bits per pixel
        info_header[14] = 8 * bytes_per_pixel;
    }

    size_t width() const {
        return image_px_width;
    }

    size_t height() const {
        return image_px_height;
    }

    void set_pixel(size_t x, size_t y, int r, int g, int b) {
        image[y][x * bytes_per_pixel + 2] = r;
        image[y][x * bytes_per_pixel + 1] = g;
        image[y][x * bytes_per_pixel + 0] = b;
    }

    void fill(int r, int g, int b) {
        for (int y = 0; y < image_px_height; ++y) {
            for (int x = 0; x < image_px_width; ++x) {
                set_pixel(x, y, r, g, b);
            }
        }
    }

    void write_to_file(const char* file_name) const {
        std::ofstream img_file(file_name, std::ios_base::binary | std::ios_base::out);

        img_file.write((char*)file_header, header_size);
        img_file.write((char*)info_header, info_header_size);

        std::vector<char> allignment(row_padding);

        for (int y = image_px_height - 1; y >= 0; --y) {
            img_file.write((char*)image[y].data(), row_width);

            img_file.write(allignment.data(), row_padding);
        }

        img_file.close();
    }
private:
    size_t image_px_width;
    size_t image_px_height;

    size_t row_width;

    size_t row_padding;

    size_t row_stride;

    size_t file_size;

    unsigned char file_header[header_size] = { 0 };
    unsigned char info_header[info_header_size] = { 0 };
    std::vector<std::vector<unsigned char>> image;
};

原文由 Jcsq6 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题