代码之家  ›  专栏  ›  技术社区  ›  cbuchart

将qpixmaps列表保存到.ico文件

  •  1
  • cbuchart  · 技术社区  · 6 年前

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

    qt是否具有这样的功能?如何保存此类文件?可能与Windows API混合?

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   cbuchart    6 年前

    在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 .