skylight.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. from PIL import Image, ImageDraw, ImageFont
  2. import os
  3. def create_name(name,img_url,output_path):
  4. font : ImageFont
  5. image1 = Image.open(img_url).convert('RGBA')
  6. if detect_language(name) == "English":
  7. font = ImageFont.truetype(f"{os.path.split(os.path.abspath('main.py'))[0]}/static/MasaFont-Regular.ttf", 120, encoding="utf-8")
  8. if len(name) > 50:
  9. return "超過字數限制"
  10. # 設定初始位置
  11. x_position = 0
  12. y_position = 0
  13. max_width = int(font.getlength(name[0])*len(name))
  14. max_height = int(font.getlength(name[0])*len(name))
  15. image = Image.new('RGBA', (max_width,max_height), (255, 255, 255, 0))
  16. draw = ImageDraw.Draw(image)
  17. text_width = draw.textlength(name[0], font=font)
  18. for char in name:
  19. draw.text((x_position, y_position), char, font=font, fill=(0, 0, 0))
  20. x_position += text_width
  21. image1.paste(image, (500, 1500),image)
  22. # 保存疊加後的圖片
  23. image1.save(output_path)
  24. else:
  25. # 選擇中文字型和大小
  26. font = ImageFont.truetype(f"{os.path.split(os.path.abspath('main.py'))[0]}/static/MasaFont-Regular.ttf", 150, encoding="utf-8")
  27. if len(name) > 5 :
  28. return "超過字數限制"
  29. # 設定初始位置
  30. x_position = 0
  31. y_position = 0
  32. max_width = int(font.getlength(name[0]))
  33. max_height = int(font.getlength(name[0])*len(name))
  34. image = Image.new('RGBA', (max_width,max_height), (255, 255, 255, 0))
  35. draw = ImageDraw.Draw(image)
  36. text_width = draw.textlength(name[0], font=font)
  37. for char in name:
  38. draw.text((x_position, y_position), char, font=font, fill=(0, 0, 0))
  39. y_position += text_width
  40. image1.paste(image, (150, 900),image)
  41. # 保存疊加後的圖片
  42. image1.save(output_path)
  43. def create_image(text, output_path, font_size=300, bg_color=(255, 255, 255), text_color=(0, 0, 0), max_width=200):
  44. # 查看語言
  45. lines : list
  46. check_tag = "en"
  47. font : ImageFont
  48. if detect_language(text) == "English":
  49. font = ImageFont.truetype(f"{os.path.split(os.path.abspath('main.py'))[0]}/static/MasaFont-Regular.ttf", 200, encoding="utf-8")
  50. if len(text) > 80:
  51. return "超過字數限制"
  52. lines = split_text_by_length(text, 15)
  53. check_tag = "en"
  54. else:
  55. # 選擇中文字型和大小
  56. font = ImageFont.truetype(f"{os.path.split(os.path.abspath('main.py'))[0]}/static/MasaFont-Regular.ttf", font_size, encoding="utf-8")
  57. if len(text) > 15 :
  58. return "超過字數限制"
  59. lines = split_chinese_text(text, max_length=4)
  60. check_tag = "ch"
  61. # 設定初始位置
  62. x_position = 0
  63. y_position = 0
  64. lines_tmp = [x.strip() for x in lines if x.strip()!='']
  65. lines = lines_tmp
  66. print(lines)
  67. line_height = font.getlength(text[0])
  68. print(line_height)
  69. max_width = int(font.getlength(text[0])*len(lines))
  70. max_height = int(font.getlength(text[0])*find_longest_segment(lines))
  71. print(max_width,max_height)
  72. if check_tag == "en" :
  73. tmp = max_width
  74. max_width = max_height
  75. max_height = tmp*2
  76. # 建立一個白色背景的圖片
  77. image = Image.new('RGBA', (max_width,max_height), (255, 255, 255, 0))
  78. draw = ImageDraw.Draw(image)
  79. line_num = 0
  80. text_width = draw.textlength(lines[0][0], font=font)
  81. if check_tag == "en" :
  82. y_position = 0
  83. # 繪製每一行文字
  84. for line in lines:
  85. x_position = 0
  86. for char in line:
  87. draw.text((x_position, y_position), char, font=font, fill=text_color)
  88. x_position += text_width
  89. y_position += line_height +50
  90. line_num += 1
  91. else :
  92. x_position = max_width - text_width
  93. # 繪製每一行文字
  94. for line in lines:
  95. y_position = 0
  96. for char in line:
  97. draw.text((x_position, y_position), char, font=font, fill=text_color)
  98. y_position += text_width
  99. x_position -= line_height
  100. line_num += 1
  101. # 儲存圖片
  102. image.save(output_path)
  103. return "成功製作文字"
  104. def overlay_images(background_path, overlay_path, output_path,name):
  105. image1 = Image.open(background_path).convert('RGBA')
  106. image2 = Image.open(overlay_path).convert('RGBA')
  107. x = (image1.width - image2.width) // 2
  108. y = (image1.height - image2.height) // 2 - 160
  109. # 將第二張圖片疊加在第一張圖片上
  110. image1.paste(image2, (x, y),image2)
  111. # 保存疊加後的圖片
  112. image1.save(f"{output_path}_tmp.png")
  113. # 顯示疊加後的圖片
  114. # image1.show()
  115. print(f"finished, saving image at {output_path}")
  116. try:
  117. create_name(name,f"{output_path}_tmp.png",output_path)
  118. except Exception as e:
  119. print( str(e))
  120. im = Image.open(output_path)
  121. name =output_path.lower().split('/')[::-1][0]
  122. webp = name.replace('png', 'webp')
  123. im.save(f"{os.path.split(os.path.abspath('main.py'))[0]}/static/tendents/{webp}", 'WebP', quality=40, )
  124. os.remove(output_path)
  125. os.remove(f"{output_path}_tmp.png")
  126. def detect_language(text):
  127. for char in text:
  128. # Check if the character falls within the range of Chinese characters
  129. if '\u4e00' <= char <= '\u9fff':
  130. return 'Chinese'
  131. # If no Chinese characters are found, assume it's English
  132. return 'English'
  133. def split_text_by_length(text, length):
  134. paragraphs = []
  135. current_paragraph = ""
  136. words = text.split()
  137. for word in words:
  138. # If adding the current word exceeds the maximum length, start a new paragraph
  139. if len(current_paragraph) + len(word) + 1 > length:
  140. paragraphs.append(current_paragraph.strip())
  141. current_paragraph = ""
  142. # Add the current word to the current paragraph
  143. current_paragraph += word + " "
  144. # Add the remaining part as the last paragraph
  145. if current_paragraph:
  146. if current_paragraph.strip():
  147. paragraphs.append(current_paragraph.strip())
  148. #print(paragraphs)
  149. return paragraphs
  150. def split_chinese_text(text, max_length=5):
  151. """
  152. Split the Chinese text into segments with a maximum length.
  153. Args:
  154. text (str): The input Chinese text.
  155. max_length (int): The maximum length of each segment. Default is 5.
  156. Returns:
  157. list: A list of segments.
  158. """
  159. segments = []
  160. current_segment = ""
  161. for char in text:
  162. # 如果当前片段加上当前字符的长度超过最大长度,就添加当前片段到segments列表中,并且重置当前片段
  163. if len(current_segment) + len(char) > max_length:
  164. segments.append(current_segment)
  165. current_segment = ""
  166. # 如果当前字符不是空格,就添加到当前片段中
  167. if char != ' ':
  168. current_segment += char
  169. else :
  170. segments.append(current_segment)
  171. current_segment = ""
  172. # 添加最后一个片段到segments列表中
  173. if current_segment:
  174. if current_segment.strip() and current_segment != '':
  175. segments.append(current_segment)
  176. return segments
  177. def find_longest_segment(segments):
  178. """
  179. Find the longest segment from the given list of segments.
  180. Args:
  181. segments (list): The list of segments.
  182. Returns:
  183. str: The longest segment.
  184. """
  185. longest_segment = ""
  186. max_length = 0
  187. for segment in segments:
  188. if len(segment) > max_length:
  189. longest_segment = segment
  190. max_length = len(segment)
  191. return len(longest_segment)
  192. if __name__ == "__main__":
  193. text = "心想事成 萬事如意"
  194. output_path = "tendents/vertical_chinese_text.png"
  195. create_image(text, output_path)
  196. print(f"圖片已儲存至 {output_path}")
  197. output_path = "combined_image.png"
  198. # 執行疊加
  199. overlay_images("tendentest.png", "vertical_chinese_text.png", output_path)