IconHelper.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import os
  2. import sys
  3. import json
  4. import hashlib
  5. from icoextract import IconExtractor
  6. from PySide6.QtCore import Qt, QFileInfo, QSize
  7. from PySide6.QtGui import QPixmap, QIcon, QImage
  8. from PySide6.QtWidgets import QFileIconProvider
  9. from Kikka.KikkaConst import *
  10. from Kikka.Utils.Singleton import singleton
  11. @singleton
  12. class IconHelper():
  13. def __init__(self):
  14. self._cache = {}
  15. self._icons = {}
  16. self.loadCache()
  17. def loadCache(self):
  18. os.makedirs(CACHE_ICON_PATH, exist_ok=True)
  19. if os.path.exists(ICON_CACHE_FILE):
  20. with open(ICON_CACHE_FILE, 'r') as fp:
  21. self._cache = json.load(fp)
  22. def saveCache(self):
  23. with open(ICON_CACHE_FILE, 'w') as fp:
  24. json.dump(self._cache, fp)
  25. def hash(self, text):
  26. return hashlib.sha256(text.encode('utf-8')).hexdigest()
  27. def getIconByHash(self, hash):
  28. if hash in self._cache.values():
  29. if hash in self._icons:
  30. return self._icons[hash]
  31. else:
  32. icon = QIcon(os.path.join(CACHE_ICON_PATH, hash + ".png"))
  33. self._icons[hash] = icon
  34. return icon
  35. return None
  36. def getIconByFile(self, filepath):
  37. hash = self.hash(filepath)
  38. if filepath in self._cache:
  39. if hash in self._icons:
  40. return self._icons[hash]
  41. else:
  42. icon_path = os.path.join(CACHE_ICON_PATH, hash + ".png")
  43. if os.path.exists(icon_path):
  44. icon = QIcon(icon_path)
  45. self._icons[hash] = icon
  46. return icon
  47. file = QFileInfo(filepath)
  48. if not file.exists():
  49. return None
  50. icon = None
  51. if file.suffix().lower() in ["exe", "dll", "mun"]:
  52. temp_icon = os.path.join(CACHE_ICON_PATH, "_temp.ico")
  53. extractor = IconExtractor(file.filePath())
  54. extractor.export_icon(temp_icon)
  55. icon = QIcon(temp_icon)
  56. available_sizes = icon.availableSizes()
  57. if not available_sizes:
  58. return None
  59. else:
  60. p = QFileIconProvider()
  61. icon = p.icon(file)
  62. if icon is None or icon.isNull():
  63. return None
  64. # for size in available_sizes:
  65. # pixmap = icon.pixmap(size)
  66. # name = "%dx%s.png" % (size.width(), size.height())
  67. # pixmap.save(os.path.join(CacheDir, name))
  68. actualSize = icon.actualSize(QSize(72, 72))
  69. pixmap = icon.pixmap(actualSize)
  70. pixmap.save(os.path.join(CACHE_ICON_PATH, hash + ".png"))
  71. self._cache[filepath] = hash
  72. return self.getIconByHash(hash)
  73. if __name__ == "__main__":
  74. from PySide6.QtWidgets import QApplication
  75. app = QApplication(sys.argv)
  76. file = r"C:\example.exe"
  77. # file = C:\example.svg"
  78. # file = C:\example.lnk"
  79. icon = IconHelper().getIconByFile(file)
  80. pixmap = icon.pixmap(64, 64)
  81. pixmap.save("icon.png")