将 QPixmaps 列表保存到.ico文件
Save a list of QPixmaps to .ico file
我有兴趣从QPixmap
图像列表(大小为16x16,32x32,48x48...)中创建单个.ico文件(具有透明度)。我在Qt的文档中没有看到任何相关的方法:QPixmap
,QImage
,QIcon
(用于存储UI状态的图像,与文件格式无关)...
Qt有这样的功能吗?如何保存此类文件?可能与Windows API混合使用?
PS:一个低级的解决方案是直接编写.ico文件,但我更感兴趣的是如果可能的话不要重新发明轮子。
Qt中似乎没有内置支持编写ICO文件,所以在这里我发布了一个代码片段,以从pixmaps列表中生成一个代码片段。希望它可能对其他人有用。
template<typename T>
void write(QFile& f, const T t)
{
f.write((const char*)&t, sizeof(t));
}
bool savePixmapsToICO(const QList<QPixmap>& pixmaps, const QString& path)
{
static_assert(sizeof(short) == 2, "short int is not 2 bytes");
static_assert(sizeof(int) == 4, "int is not 4 bytes");
QFile f(path);
if (!f.open(QFile::OpenModeFlag::WriteOnly)) return false;
// Header
write<short>(f, 0);
write<short>(f, 1);
write<short>(f, pixmaps.count());
// Compute size of individual images
QList<int> images_size;
for (int ii = 0; ii < pixmaps.count(); ++ii) {
QTemporaryFile temp;
temp.setAutoRemove(true);
if (!temp.open()) return false;
const auto& pixmap = pixmaps[ii];
pixmap.save(&temp, "PNG");
temp.close();
images_size.push_back(QFileInfo(temp).size());
}
// Images directory
constexpr unsigned int entry_size = sizeof(char) + sizeof(char) + sizeof(char) + sizeof(char) + sizeof(short) + sizeof(short) + sizeof(unsigned int) + sizeof(unsigned int);
static_assert(entry_size == 16, "wrong entry size");
unsigned int offset = 3 * sizeof(short) + pixmaps.count() * entry_size;
for (int ii = 0; ii < pixmaps.count(); ++ii) {
const auto& pixmap = pixmaps[ii];
if (pixmap.width() > 256 || pixmap.height() > 256) continue;
write<char>(f, pixmap.width() == 256 ? 0 : pixmap.width());
write<char>(f, pixmap.height() == 256 ? 0 : pixmap.height());
write<char>(f, 0); // palette size
write<char>(f, 0); // reserved
write<short>(f, 1); // color planes
write<short>(f, pixmap.depth()); // bits-per-pixel
write<unsigned int>(f, images_size[ii]); // size of image in bytes
write<unsigned int>(f, offset); // offset
offset += images_size[ii];
}
for (int ii = 0; ii < pixmaps.count(); ++ii) {
const auto& pixmap = pixmaps[ii];
if (pixmap.width() > 256 || pixmap.height() > 256) continue;
pixmap.save(&f, "PNG");
}
return true;
}
代码也可在 GitHub 中使用。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 将 QPixmaps 列表保存到.ico文件
- 绘图 *.ICO文件在WXWIDGETS上
- 从Qt资源文件加载ICO时出现问题