为什么我的bmp作家不工作?

时间:2015-03-19 21:47:29

标签: c++ file-io bmp ostream

我试图编写一个简单的函数,将一些图像数据保存为位图。我生成的数据是3601 x 3601.我在调试器中验证了传递给函数的所有数据都是正确的。我还验证了焊盘尺寸与我期望的24位BMP宽度3601(padSize = 1)一样。

这个创建的位图要比我用相同尺寸的绘制创建的位图大得多,这意味着这里写的东西太多了。我把这个文件比作一个类似大小的位图,标题是相同的,所以我不认为我的问题就在那里。我认为我在charbuffer上的写命令必须写得比预期更多,但我无法弄清楚原因。任何帮助表示赞赏。

void SaveBMPData(string fname, unsigned char *data, int imgWid, int imgHei)
{

    ofstream file;
    file.open(fname.c_str(), std::ios::out);

    if (file.is_open())
    {
        //string fname = "APnormal.bmp";
        cout << "INFO >> Saving BMP data: " << fname << "." << endl;

        //write header
        unsigned char fileinfo[14] = {
            'B', 'M', // magic
            0, 0, 0, 0, // size in bytes
            0, 0, // app data
            0, 0, // app data
            40 + 14, 0, 0, 0 // start of data offset
        };
        unsigned char info[40] = {
            40, 0, 0, 0, // info hd size
            0, 0, 0, 0, // width
            0, 0, 0, 0, // heigth
            1, 0, // number color planes
            24, 0, // bits per pixel
            0, 0, 0, 0, // compression is none
            0, 0, 0, 0, // image bits size
            0x13, 0x0B, 0, 0, // horz resoluition in pixel / m
            0x13, 0x0B, 0, 0, // vert resolutions (0x03C3 = 96 dpi, 0x0B13 = 72 dpi)
            0, 0, 0, 0, // #colors in pallete
            0, 0, 0, 0, // #important colors
        };    

        int w = imgWid;
        int h = imgHei;

        int padSize = (4 - ((w * 3) % 4)) % 4;
        int sizeData = w*h * 3 +h*padSize;
        int sizeAll = sizeData + sizeof(fileinfo) + sizeof(info);

        fileinfo[2] = (unsigned char)(sizeAll);
        fileinfo[3] = (unsigned char)(sizeAll >> 8);
        fileinfo[4] = (unsigned char)(sizeAll >> 16);
        fileinfo[5] = (unsigned char)(sizeAll >> 24);  

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

        info[8] = (unsigned char) (h);
        info[9] = (unsigned char) (h >> 8);
        info[10] = (unsigned char)(h >> 16);
        info[11] = (unsigned char)(h >> 24);

        info[20] = (unsigned char)(sizeData);
        info[21] = (unsigned char)(sizeData >> 8);
        info[22] = (unsigned char)(sizeData >> 16);
        info[23] = (unsigned char)(sizeData >> 24);

        file.write((char*)fileinfo, sizeof(fileinfo));
        file.write((char*)info, sizeof(info));

        unsigned char *charbuffer = new unsigned char[w * 3 + padSize];

        for (int y = 0; y<h; y++)
        {
            for (int x = 0; x<w; x++)
            {
                unsigned char red = data[(x + y*imgWid) * 3];
                unsigned char green = data[(x + y*imgWid) * 3 + 1];
                unsigned char blue = data[(x + y*imgWid) * 3 + 2];
                charbuffer[x * 3    ] = blue;
                charbuffer[x * 3 + 1] = green;
                charbuffer[x * 3 + 2] = red;

            }
            file.write((char *)(void*)charbuffer, w*3+padSize);

        }
        file.close();
        delete [] charbuffer;
    }
    else
    {
        cout << "can't read file.\n";
    }

}

2 个答案:

答案 0 :(得分:1)

您需要以二进制模式打开文件,否则任何值为0x0a的像素组件都将导致写入0x0d 0x0a文件。

file.open(fname.c_str(), std::ios::out | std::ios::binary);

答案 1 :(得分:0)

你是否将绘图中的位图保存为24位bmp?

我强烈建议在互联网上获取一些代码,例如:http://tipsandtricks.runicsoft.com/Cpp/BitmapTutorial.html并查看/使用该代码。

我会避免使用带有值和注释(info,fileinfo)的数组,并使用真实的具体结构来定义属性。

您的问题应该很容易理解,但IMO最好使用已编写的代码,因为这已经多次完成所以