祝大家好心:)
几天前,我终于设法创建了一个功能性的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;
};
};
答案 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
中保留内存。这将减少扩展缓冲区时需要进行的副本数量。虽然性能提升可能并不显着,但它绝对有帮助。我建议通过分析器运行代码,以查看所有瓶颈所在并进行相应优化。