如何加快我的.bmp课程?

时间:2013-08-03 18:42:46

标签: c++ file file-io fstream ofstream

祝大家好心:)

几天前,我终于设法创建了一个功能性的C ++类来制作.bmp图像。虽然它的功能(没有错误)但在速度方面效率不高(在我看来)。做一些测试,看看编写不同尺寸的图像花了多少时间我得到了这些结果:

Image Dimensions   Time taken(in seconds)     Comparison to the 1000x1000 image
10x100             0.0491                     x 1000 = 49.1 seconds
100x100            0.2471                     x 100  = 24.7 seconds
100x1000           2.3276                     x 10   = 23.3 seconds
1000x1000          22.515                     x 1    = 22.5 seconds
1000x10000         224.76                     \ 10   = 22.4 seconds

例如,10x100图像有1000个像素(每个像素带有ARGB通道[32位或4个字节])加上标题的54个字节,写入4054个字节(char)需要0.05秒。

我觉得这超级慢,因为我的电脑可以像一两秒那样复制一个~85MB的文件。我正在使用fstream来写入磁盘,并且任何有助于让课程更快的帮助表示赞赏。谢谢!!!

我的课程名为SimpleBMP,在这里它(我只提供了令人敬畏的功能):

#include <fstream>


class SimpleBMP{
    struct PIXEL{
        unsigned char A, R, G, B;
    }*PixelArray;
    unsigned char *BMPHEADER, *BMPINFOHEADER;
    std::string DATA;
    unsigned int Size_Of_BMP, Size_Of_PixelArray;
    int BMP_Width, BMP_Height;

public:

void SetPixel(int Column, int Row, unsigned char A, unsigned char R, unsigned char G, unsigned char B){
    PixelArray[(Row*BMP_Width)+Column].A = A;
    PixelArray[(Row*BMP_Width)+Column].R = R;
    PixelArray[(Row*BMP_Width)+Column].G = G;
    PixelArray[(Row*BMP_Width)+Column].B = B;
};

bool MakeImage(std::string Name){
    Name.append(".bmp");
    std::ofstream OffFile(Name, std::ios::out|std::ios::binary);
    if(OffFile.is_open()){
        DATA.clear();
        for(int temp = 0; temp < 14; temp++){
            BMPHEADER[temp] = 0x00;
        };
        BMPHEADER[0] = 'B';
        BMPHEADER[1] = 'M';
        BMPHEADER[2] = Size_Of_BMP;
        BMPHEADER[3] = (Size_Of_BMP >> 8);
        BMPHEADER[4] = (Size_Of_BMP >> 16);
        BMPHEADER[5] = (Size_Of_BMP >> 24);
        BMPHEADER[10] = 0x36;



        for(int temp = 0; temp < 40; temp++){
            BMPINFOHEADER[temp] = 0x00;
        };
        BMPINFOHEADER[0] = 0x28;

        for(int temp = 0; temp < 4; temp++){
            BMPINFOHEADER[temp+4] = (BMP_Width >> (temp*8));
        };
        for(int temp = 0; temp < 4; temp++){
            BMPINFOHEADER[temp+8] = (BMP_Height >> (temp*8));
        };  
        BMPINFOHEADER[12] = 0x01;
        BMPINFOHEADER[14] = 0x20;

        for(int temp = 0; temp < 4; temp++){
            BMPINFOHEADER[temp+20] = (Size_Of_PixelArray >> (temp*8));
        };
        BMPINFOHEADER[24] = 0x13;
        BMPINFOHEADER[25] = 0x0b;
        BMPINFOHEADER[28] = 0x13;
        BMPINFOHEADER[29] = 0x0b;



        for(int temp = 0; temp < 14; temp++){
            DATA.push_back(BMPHEADER[temp]);
        };
        for(int temp = 0; temp < 40; temp++){
            DATA.push_back(BMPINFOHEADER[temp]);
        };
        for(int temp = 0; temp < (Size_Of_PixelArray/4); temp++){
            DATA.push_back(PixelArray[temp].B);
            DATA.push_back(PixelArray[temp].G);
            DATA.push_back(PixelArray[temp].R);
            DATA.push_back(PixelArray[temp].A);
        };  
        OffFile.write(DATA.c_str(), Size_Of_BMP);
        OffFile.close();
        return true;
    }
    else
        return false;
};

};

2 个答案:

答案 0 :(得分:0)

如果您知道自己在小端机器上,则可以完全跳过重新打包数据,并直接存储像素数据。

OffFile.Write((char *)&PixelArray, Size_Of_BMP);

它可能不那么便携,但它肯定会加速保存到文件。

(你可以有一个

#ifdef LITTLE_ENDIAN
struct PIXEL{
    unsigned char A, R, G, B;
};
#else
struct PIXEL{
    unsigned char B, G, R, A;
};
#endif    

PIXEL *PixelArray;
声明中的

答案 1 :(得分:0)

运行测试时,您应该在发布模式下编译项目。大多数环境中的 Debug 模式引入了额外的检查和代码。链接的 debug 库还可以包含其他检查,例如边界检查和验证 release 模式中不存在的迭代器。所有这些都会引入在发布模式下不存在的性能命中。

您可以应用其他优化,例如在加载数据之前在DATA中保留内存。这将减少扩展缓冲区时需要进行的副本数量。虽然性能提升可能并不显着,但它绝对有帮助。我建议通过分析器运行代码,以查看所有瓶颈所在并进行相应优化。