将文件夹下面的文件数据以数组形式保存到CPP文件中,以std::map方式来索引文件信息。
使用场景:不希望把文件数据直接暴露给用户。
效果如下:
代码参考:
#include <qdir.h>
#include <qicon.h>
#include <qpixmap.h>
#include <fstream>
#include <iostream>
struct MyIconInfo
{
std::string name;
size_t size;
std::string format;
const char* data;
};
std::map<std::string, MyIconInfo> icon_map
{
};
bool getIconInfo(std::string name, MyIconInfo& icon_info)
{
std::map<std::string, MyIconInfo>::iterator it;
it = icon_map.find(name);
if (it != icon_map.end())
{
icon_info = it->second;
return true;
}
else
{
return false;
}
}
QIcon getIcon(std::string name)
{
MyIconInfo info;
if (getIconInfo(name, info))
{
QPixmap icon;
QByteArray datas = QByteArray::fromRawData(info.data, info.size);
bool ok = icon.loadFromData(datas, info.format.c_str());
if (ok)
{
//icon.save(QString::fromStdString(info.name) + QString("_out.") + QString::fromStdString(info.format));
return icon;
}
else
{
return QIcon("");
}
}
else
{
return QIcon("");
}
}
int main()
{
QString icon_dir = "./icon/";// dirname
const char output_cpp[] = "icon_data.cpp";// cpp filename
FILE *pout = fopen(output_cpp, "w");
QDir dir(icon_dir);
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Size | QDir::Reversed);
QFileInfoList list = dir.entryInfoList();
std::vector<MyIconInfo> infos;
for (int i = 0; i < list.size(); ++i)
{
QFileInfo fileInfo = list.at(i);
if (pout)
{
std::fstream files((icon_dir + fileInfo.fileName()).toStdString(), std::ios::binary | std::ios::in);
if (files.is_open())// open file
{
MyIconInfo single_info;
single_info.name = fileInfo.baseName().toStdString();// filename
single_info.format = (fileInfo.completeSuffix()).toStdString();// suffix
// get file size
files.seekg(0, std::ios::end);
std::streamsize size = files.tellg();
files.seekg(0, std::ios::beg);
single_info.size = size;
// read icon file and put format string to output file
std::vector<char> buffer(size);
unsigned char* p = (unsigned char*)buffer.data();
if (files.read(buffer.data(), size))
{
fprintf(pout, "\n static char %s[] =\n{\n ", fileInfo.baseName().toStdString().c_str());
for (int i = 0; i < size; i++)
{
fprintf(pout, "0x%02x, ", p[i]);
if ((i != 0) && (0 == (i % 16)))
{
fprintf(pout, "\n ", p[i]);
}
}
fprintf(pout, "\n };\n\n");
}
files.close();
infos.push_back(single_info);
}
}
}
// generate icon data map. you can find a icon data by icon name
if (pout)
{
fprintf(pout, "\
struct MyIconInfo\n\
{\n\
std::string name;\n\
size_t size;\n\
std::string format;\n\
const char* data;\n\
};\n\
std::map<std::string, MyIconInfo> icon_map\n\
{\n");
for (auto& info : infos)
{
fprintf(pout, " { \"%s\", MyIconInfo{ \"%s\", %u, \"%s\", %s } },\n", info.name.c_str(), info.name.c_str(), info.size, info.format.c_str(), info.name.c_str());
}
fprintf(pout, "\
};\n");
fclose(pout);
}
// test
int count = 0;
for (auto& info : infos)
{
QIcon icon = getIcon(info.name);
bool save = icon.pixmap(icon.availableSizes().first()).save(QString::number(count++) + QString::fromStdString(info.name) + QString(".") + QString::fromStdString(info.format), info.format.c_str());
std::cout << "Icon [" << info.name << "] save to file: " << save << std::endl;
}
}