Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

stitchify.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """ Converts pixel-art images into cross-stitch patterns.
  2. This tool assumes that 1px = 1 stitch.
  3. TODO:
  4. * Accept image name from command line. (DONE)
  5. * Change characters to symbols for ease of reading.
  6. * Expand number of symbols.
  7. * Create image from symbolized pixels instead of just printing to screen. (DONE)
  8. * Add grid lines and edge labels to image. (DONE)
  9. * Add legend to image, based on the `symbols` dictionary. (DONE)
  10. * Correspond hex colors to floss colors, where possible.
  11. * (Maybe) add stitch count for each color. (DONE)
  12. * (Maybe) add GUI.
  13. """
  14. __author__ = "Noëlle Anthony"
  15. __version__ = "0.3.0"
  16. import sys
  17. from PIL import Image, ImageDraw
  18. from collections import defaultdict
  19. def main(img_name):
  20. img = Image.open(img_name)
  21. oimg_name_bits = img_name.split(".")
  22. oimg_name = "".join(oimg_name_bits[:-1]) + "_pattern." + oimg_name_bits[-1]
  23. w,h = img.size
  24. symbols = defaultdict(str)
  25. symbols["transparent"] = " "
  26. characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  27. symbol_counts = defaultdict(int)
  28. # l = 0
  29. lines = []
  30. for i in range(h):
  31. line = []
  32. # k = 0
  33. for j in range(w):
  34. c = "".join(["{}{}".format(hex(x//16).split('x')[-1], hex(x%16).split('x')[-1]) for x in list(img.getpixel((j,i)))])
  35. d = " "
  36. if c[-2:] == "ff":
  37. cs = c[:-2]
  38. if cs not in symbols.keys():
  39. symbols[cs] = characters[0]
  40. characters = characters[1:]
  41. symbol_counts[cs] += 1
  42. d = symbols[cs]
  43. line.append(d)
  44. # print(d, end="")
  45. # k += 1
  46. # if k == 9:
  47. # print("|", end="")
  48. # k = 0
  49. lines.append(line)
  50. # print()
  51. # l += 1
  52. # if l == 9:
  53. # for ww in range(int(w*1.1)+1):
  54. # if (ww+1)%10 == 0:
  55. # print("+", end="")
  56. # else:
  57. # print("-", end="")
  58. # l = 0
  59. # print()
  60. # print("\nLEGEND")
  61. legend = []
  62. keys = 0
  63. for k,v in symbols.items():
  64. if v != " ":
  65. keys += 1
  66. legend.append("{}: #{} ({}ct)".format(v, k, symbol_counts[k]))
  67. print("{} keys".format(keys))
  68. # print("\n".join(legend))
  69. owid, ohgt = (w*10)+10, (h*10)+10+(15*(int(keys/3)+1))
  70. print((owid, ohgt))
  71. oimg = Image.new("RGB", (owid, ohgt), "white")
  72. draw = ImageDraw.Draw(oimg)
  73. for ww in range(1, w+1):
  74. posx = ww * 10
  75. linecolor = 0 if posx % 100 == 0 else (128,128,128)
  76. linewidth = 2 if posx % 100 == 0 else 1
  77. draw.line((posx, 10, posx, (h*10)), fill=linecolor, width=linewidth)
  78. for hh in range(1, h+1):
  79. posy = hh * 10
  80. linecolor = 0 if posy % 100 == 0 else (128,128,128)
  81. linewidth = 2 if posx % 100 == 0 else 1
  82. draw.line((10, posy, owid, posy), fill=linecolor, width=linewidth)
  83. char_positions = [x*10+4 for x in range(1,h+1)]
  84. # print(char_positions)
  85. #char_colors = {" ": (0,0,0), "A": (0,0,0), "B": (128,0,0), "C": (0,128,0), "D": (0,255,255), "E": (128,128,0), "F": (128,0,128), "G": (0,0,0)}
  86. adjust = 0
  87. for line in lines:
  88. for char in range(len(line)):
  89. draw.text((char_positions[char], char_positions[0]-4+adjust), line[char], fill=0)
  90. adjust += 10
  91. legend_out = ""
  92. item_ct = 0
  93. for item in legend:
  94. item_ct += 1
  95. legend_out += item
  96. if item_ct % 3 == 0:
  97. legend_out += "\n"
  98. else:
  99. legend_out += " "
  100. draw.text((20, (h*10)+10), legend_out, fill=0)
  101. oimg.save(oimg_name)
  102. print("Saved {}".format(oimg_name))
  103. if __name__ == "__main__":
  104. #print(len(sys.argv))
  105. #print(sys.argv[1])
  106. if len(sys.argv) >= 2:
  107. img_name = sys.argv[1]
  108. else:
  109. img_name = "test.png"
  110. main(img_name)