make_logo_transparent.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. """
  2. Make logo.png background transparent (vectorized, fast).
  3. Writes to logo.png.tmp then replaces — avoids corrupting the file on failure.
  4. Tune WHITE_* if edges of the logo are eaten or background remains.
  5. """
  6. from __future__ import annotations
  7. import os
  8. import numpy as np
  9. from PIL import Image
  10. PATH = r"D:\worksspace\s202226701051\word-app\src\assets\icon\logo.png"
  11. TMP = PATH + ".tmp.png"
  12. # Pixels matching "light background" become transparent
  13. WHITE_MIN = 236 # channel minimum for near-white
  14. WHITE_AVG = 242 # average RGB
  15. WHITE_SPREAD = 28 # max(r,g,b)-min(r,g,b); logo colors usually higher spread
  16. def main() -> None:
  17. im = Image.open(PATH).convert("RGB")
  18. rgb = np.array(im)
  19. r = rgb[:, :, 0].astype(np.int16)
  20. g = rgb[:, :, 1].astype(np.int16)
  21. b = rgb[:, :, 2].astype(np.int16)
  22. avg = (r + g + b) / 3
  23. spread = np.maximum(np.maximum(r, g), b) - np.minimum(np.minimum(r, g), b)
  24. near_white = (
  25. (r >= WHITE_MIN) & (g >= WHITE_MIN) & (b >= WHITE_MIN)
  26. ) | ((avg >= WHITE_AVG) & (spread <= WHITE_SPREAD))
  27. rgba = np.zeros((rgb.shape[0], rgb.shape[1], 4), dtype=np.uint8)
  28. rgba[:, :, :3] = rgb
  29. rgba[:, :, 3] = np.where(near_white, 0, 255).astype(np.uint8)
  30. out = Image.fromarray(rgba, "RGBA")
  31. out.save(TMP, "PNG", optimize=True)
  32. Image.open(TMP).load()
  33. os.replace(TMP, PATH)
  34. print("OK:", PATH, "transparent count:", int(near_white.sum()))
  35. if __name__ == "__main__":
  36. main()