gpt4 book ai didi

c++ - 将 QPixmaps 列表保存到 .ico 文件

转载 作者:行者123 更新时间:2023-11-30 04:52:38 26 4
gpt4 key购买 nike

我有兴趣从 QPixmap 图像列表(尺寸为 16x16、32x32、48x48...)中创建单个 .ico 文件(具有透明度)。我在Qt的文档中没有看到任何相关的方法:QPixmap, QImage, QIcon(用于存储UI状态的图像,不相关到文件格式)...

Qt有这样的功能吗?我怎样才能保存这样的文件?可能与 Windows API 混合使用?

PS:低级解决方案是直接编写 .ico file ,但我更感兴趣的是尽可能不重新发明轮子。

最佳答案

似乎在 Qt 中没有内置支持编写 ICO 文件,所以我在这里发布一个代码片段以从像素图列表中生成一个。希望它可能对其他人有用。

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 中找到.

关于c++ - 将 QPixmaps 列表保存到 .ico 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54288411/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com