img2array.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. # Python tool to convert an image to C array for small3dlib.
  2. #
  3. # by drummyfish
  4. # released under CC0 1.0.
  5. import sys
  6. from PIL import Image
  7. def printHelp():
  8. print("Convert image to C array for small3dlib.")
  9. print("usage:\n")
  10. print(" python img2array.py [-xW -yH -h -nS -pT -5] file\n")
  11. print(" -xW set width of the output to W pixels")
  12. print(" -yH set height of the output to H pixels")
  13. print(" -h include header guards (for texture per file)")
  14. print(" -nS use the name S for the texture (defaut: \"texture\")")
  15. print(" -pT use palette from file T and indexed colors (otherwise direct colors)")
  16. print(" -5 use 565 format instead of RGB8")
  17. print("");
  18. print("by Miloslav \"drummyfish\" Ciz")
  19. print("released under CC0 1.0")
  20. def rgbTo565(rgb):
  21. return ((rgb[0] >> 3) << 11) | ((rgb[1] >> 2) << 5) | ((rgb[2] >> 3))
  22. if len(sys.argv) < 2:
  23. printHelp()
  24. quit()
  25. FILENAME = ""
  26. PALETTE = ""
  27. USE_PALETTE = False
  28. NAME = "texture"
  29. GUARDS = False
  30. OUT_WIDTH = 64
  31. OUT_HEIGHT = 64
  32. USE_565 = False
  33. for s in sys.argv:
  34. if s [:2] == "-x":
  35. OUT_WIDTH = int(s[2:])
  36. elif s [:2] == "-y":
  37. OUT_HEIGHT = int(s[2:])
  38. elif s == "-h":
  39. GUARDS = True
  40. elif s[:2] == "-n":
  41. NAME = s[2:]
  42. elif s[:2] == "-5":
  43. USE_565 = True
  44. elif s[:2] == "-p":
  45. PALETTE = s[2:]
  46. USE_PALETTE = True
  47. else:
  48. FILENAME = s
  49. imageArray = []
  50. paletteColors = []
  51. paletteArray = []
  52. image = Image.open(FILENAME).convert("RGB")
  53. pixels = image.load()
  54. if USE_PALETTE > 0:
  55. palette = Image.open(PALETTE).convert("RGB")
  56. pixelsPal = palette.load()
  57. for y in range(palette.size[1]):
  58. for x in range(palette.size[0]):
  59. c = pixelsPal[x,y]
  60. paletteColors.append(c)
  61. if USE_565:
  62. paletteArray.append(rgbTo565(c))
  63. else:
  64. paletteArray.append(c[0])
  65. paletteArray.append(c[1])
  66. paletteArray.append(c[2])
  67. image2 = Image.new("RGB",(OUT_WIDTH,OUT_HEIGHT),color="white")
  68. pixels2 = image2.load()
  69. for y in range(OUT_HEIGHT):
  70. for x in range(OUT_WIDTH):
  71. coord = (
  72. int(x / float(OUT_WIDTH) * image.size[0]),
  73. int(y / float(OUT_HEIGHT) * image.size[1]))
  74. pixel = pixels[coord]
  75. if USE_PALETTE:
  76. closestIndex = 0
  77. closestDiff = 1024
  78. # find the index of the closest color:
  79. for i in range(len(paletteColors)):
  80. c = paletteColors[i]
  81. diff = abs(pixel[0] - c[0]) + abs(pixel[1] - c[1]) + abs(pixel[2] - c[2])
  82. if diff < closestDiff:
  83. closestIndex = i
  84. closestDiff = diff
  85. imageArray.append(closestIndex)
  86. pixels2[x,y] = paletteColors[closestIndex]
  87. else:
  88. if USE_565:
  89. imageArray.append(rgbTo565(pixel))
  90. else:
  91. imageArray.append(pixel[0])
  92. imageArray.append(pixel[1])
  93. imageArray.append(pixel[2])
  94. pixels2[x,y] = pixel
  95. #-----------------------
  96. def printArray(array, name, sizeString, dataType="const uint8_t"):
  97. print(dataType + " " + name + "[" + sizeString + "] = {")
  98. arrayString = ""
  99. lineLen = 0
  100. for v in array:
  101. item = str(v) + ","
  102. lineLen += len(item)
  103. if lineLen > 80:
  104. arrayString += "\n"
  105. lineLen = len(item)
  106. arrayString += item
  107. print(arrayString[:-1])
  108. print("}; // " + name)
  109. if GUARDS:
  110. print("#ifndef " + NAME.upper() + "_TEXTURE_H")
  111. print("#define " + NAME.upper() + "_TEXTURE_H\n")
  112. if USE_PALETTE:
  113. printArray(paletteArray,NAME + "Palette",str(len(paletteArray)),"const uint16_t" if USE_565 else "const uint8_t")
  114. print("")
  115. print("#define " + NAME.upper() + "_TEXTURE_WIDTH " + str(OUT_WIDTH))
  116. print("#define " + NAME.upper() + "_TEXTURE_HEIGHT " + str(OUT_HEIGHT))
  117. print("")
  118. printArray(imageArray,NAME + "Texture",str(len(imageArray)))
  119. if GUARDS:
  120. print("\n#endif // guard")
  121. image2.save(NAME + "_preview.png")