C ++创建位图文件 - 不支持查看

时间:2014-08-21 03:10:25

标签: c++ bitmap

我正在设置一个图形程序,但是我的初始测试用例是用于创建位图。我似乎得到了一个不受支持的文件"尝试查看创建的图像时出错。起初它是在bitmap.h unsigned char color[3] = {(char)floor(blue), (char)floor(green), (char)floor(red)};认为演员需要为int,但这并没有让步。

color.h

#ifndef _COLOR_H
#define _COLOR_H

class Color {
public: 
    double r, g, b;

    Color() {};
    ~Color() {};
    Color(double _r, double _g, double _b) : r(_r/255), g(_g/255), b(_b/255) {}

    // omitted operator overloads and print method not used in test case
};

#endif

bitmap.h

#ifndef _BITMAP_H
#define _BITMAP_H

void savebmp(const char* filename, int width, int height, int dpi, Color* data) {
    FILE *f;
    int k = width * height;
    int s = 4 * k;
    int filesize = 54 + s;

    int m = static_cast<int>(39.375);
    int ppm = dpi * m; // pixels per meter

    unsigned char bmpfileheader[14] = { 
        'B', 'M', 0, 0, 0, 0, 0, 
         0, 0, 0, 0, 0, 0, 0 
    };

    unsigned char bmpinfoheader[40] = {
        40, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 1, 0, 24, 0
    };


    // Unsure about this implementation - read more about bitmap creading
    bmpfileheader[2] = (unsigned char)(filesize);
    bmpfileheader[3] = (unsigned char)(filesize >> 8);
    bmpfileheader[4] = (unsigned char)(filesize >> 16);
    bmpfileheader[5] = (unsigned char)(filesize >> 24);

    bmpinfoheader[4] = (unsigned char)(width);
    bmpinfoheader[5] = (unsigned char)(width >> 8);
    bmpinfoheader[6] = (unsigned char)(width >> 16);
    bmpinfoheader[7] = (unsigned char)(width >> 24);

    bmpinfoheader[8] = (unsigned char)(height);
    bmpinfoheader[9] = (unsigned char)(height >> 8);
    bmpinfoheader[10] = (unsigned char)(height >> 16);
    bmpinfoheader[11] = (unsigned char)(height >> 24);

    bmpinfoheader[21] = (unsigned char)(s);
    bmpinfoheader[22] = (unsigned char)(s >> 8);
    bmpinfoheader[23] = (unsigned char)(s >> 16);
    bmpinfoheader[24] = (unsigned char)(s >> 24);

    bmpinfoheader[25] = (unsigned char)(ppm);
    bmpinfoheader[26] = (unsigned char)(ppm >> 8);
    bmpinfoheader[27] = (unsigned char)(ppm >> 16);
    bmpinfoheader[28] = (unsigned char)(ppm >> 24);

    bmpinfoheader[29] = (unsigned char)(ppm);
    bmpinfoheader[30] = (unsigned char)(ppm >> 8);
    bmpinfoheader[31] = (unsigned char)(ppm >> 16);
    bmpinfoheader[32] = (unsigned char)(ppm >> 24);

    fopen_s(&f, filename, "wb");
    fwrite(bmpfileheader, 1, 14, f);
    fwrite(bmpinfoheader, 1, 40, f);

    for (int i = 0; i < k; i++) {
        Color rgb = data[i];

        double red = data[i].r * 255;
        double green = data[i].g * 255;
        double blue = data[i].b * 255;

        unsigned char color[3] = {(char)floor(blue), (char)floor(green), (char)floor(red)};

        fwrite(color, 1, 3, f);
    }
    fclose(f);
}

#endif

Main.cpp的

#include <iostream>
#include <fstream>
#include <cmath>
#include "color.h"
#include "bitmap.h"

int element;

int main(int argc, char **argv) {
    int dpi = 72;
    int width = 640;
    int height = 480;
    int n = width * height;
    Color *pixels = new Color[n]; // look into smart pointers

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            // element position in pixels array
            element = y * width + x;

            pixels[element] = Color(23, 76, 210);
        }
    }

    savebmp("practice.bmp", width, height, dpi, pixels);
    // should generate solid blue image

    std::getchar();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

一些事情:

如果你要留下漏洞,那么将这些字节数组更好memset为全零。你确定每个字节的内容是什么吗?你应该是。

我只能假设您正在填充BITMAPINFOHEADER结构。为什么不使用结构?即使你没有来自它的标题,你也可以自己定义它并保存自己与字节数组的混淆。

接下来,从第bmpinfoheader[21] = (unsigned char)(s);行开始,您似乎有一个一个接一个。字段biSizeImagebyte开始,索引 20 ,而不是21。从那里开始,代码将继续在您的代码中继续。

最后,像素逐行存储,然后填充到4字节对齐。您在内部循环中在其高度上枚举pixels,因此您基本上逐列逐列。别忘了填充!您可以使用以下方法计算需要填充的字节数:

4 - (sizeOfRowInBytes % 4)

希望这会对你有所帮助。您可能会发现this Wikipedia page很有用。