detail_generate_base.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. import settings
  2. import os
  3. try:
  4. is_test_plugins = settings.is_test_plugins
  5. except:
  6. is_test_plugins = False
  7. if is_test_plugins:
  8. from custom_plugins.plugins_mode.pic_deal import PictureProcessing
  9. else:
  10. from plugins_mode.pic_deal import PictureProcessing
  11. from PIL import Image
  12. import shutil
  13. from service.base import get_images, check_path, get_image_mask
  14. from natsort import ns, natsorted
  15. # import math
  16. from PIL import ImageFont
  17. import settings
  18. class DetailBase(object):
  19. def __init__(self, goods_no, goods_no_value: dict, out_put_dir, windows=None, excel_data=None,
  20. assigned_page_list=None, output_queue=None):
  21. self.goods_no = goods_no
  22. self.output_queue = output_queue
  23. self.out_put_dir = out_put_dir
  24. self.deal_pic_func_list = []
  25. self.goods_no_value = goods_no_value
  26. self.root = ""
  27. self.windows = windows
  28. self.template_name = None
  29. print(goods_no_value)
  30. # 重新解析为新的数据结构
  31. self.data = {}
  32. self.detailed_images = []
  33. self.assigned_page_list = assigned_page_list
  34. self.overlay_pic_dict = {}
  35. self.init()
  36. # for goods_art_no_dict in self.goods_no_value["货号资料"]:
  37. # print(goods_art_no_dict)
  38. #
  39. # raise 1
  40. if excel_data:
  41. ig_keys = ["模板名称"]
  42. for k, v in excel_data.items():
  43. if k not in ig_keys:
  44. self.goods_no_value[k] = v
  45. def del_detail_folder(self):
  46. out_path = "{out_put_dir}/{goods_no}".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  47. if not os.path.exists(out_path):
  48. return
  49. try:
  50. shutil.rmtree(out_path)
  51. except BaseException as e:
  52. print("删除文件夹失败", e)
  53. def run_all(self):
  54. if self.template_name:
  55. self.out_put_dir = "{}/{}".format(self.out_put_dir, self.template_name)
  56. print("===================detailed_images=================")
  57. # 如果没有指定页面,则删除指定目录下的对应的详情文件夹
  58. if not self.assigned_page_list:
  59. self.del_detail_folder()
  60. detailed_images = self.deal_details()
  61. self.create_folder(self.out_put_dir)
  62. detail_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  63. self.create_folder(detail_path)
  64. self.save_to_png(detailed_images=detailed_images, detail_path=detail_path)
  65. # 生成拼接图
  66. self.generate_spliced_picture()
  67. # ------------移动其他图片---------------------
  68. # 获取主图模板列表
  69. main_pic_path_list = DetailBase.get_temp_pic_info(root=self.root)["main_pic_path_list"]
  70. if not main_pic_path_list:
  71. self.move_other_pic(move_main_pic=True)
  72. else:
  73. self.move_other_pic(move_main_pic=True)
  74. if not self.assigned_page_list:
  75. self.deal_all_main_pic()
  76. else:
  77. if "主图" in self.assigned_page_list:
  78. self.deal_all_main_pic()
  79. return True
  80. # 生成各个详情图切片
  81. def deal_details(self):
  82. detailed_images = []
  83. for index, func in enumerate(self.deal_pic_func_list):
  84. image_pp = func()
  85. if not self.assigned_page_list:
  86. self.image_list_append(detailed_images, image_pp)
  87. else:
  88. index = "{}".format(index + 1)
  89. if index in self.assigned_page_list:
  90. self.image_list_append(detailed_images, image_pp)
  91. else:
  92. self.image_list_append(detailed_images, {"mes": "不生成"})
  93. return [x for x in detailed_images if x]
  94. # 生成拼接的图片
  95. def generate_spliced_picture(self):
  96. detail_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  97. if not os.path.exists(detail_path):
  98. return
  99. detailed_images = []
  100. for image_data in get_images(detail_path):
  101. detailed_images.append(PictureProcessing(image_data["file_path"]))
  102. # 生成拼接图
  103. img = self.add_pic(detailed_images)
  104. join_path = "{out_put_dir}/{goods_no}/拼接图".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  105. self.create_folder(join_path)
  106. img.save("{}/1.jpg".format(join_path), format="JPEG")
  107. def image_list_append(self, image_list: list, data):
  108. self.check_state_end()
  109. if isinstance(data, list):
  110. image_list.extend(data)
  111. else:
  112. image_list.append(data)
  113. def save_to_png(self, detailed_images, detail_path):
  114. self.check_state_end()
  115. for index, pp in enumerate(detailed_images):
  116. if isinstance(pp, dict):
  117. continue
  118. pp.im.save("{}/{}({}).png".format(detail_path, self.goods_no, str(index + 11).zfill(2)))
  119. def check_state_end(self):
  120. if self.windows is not None:
  121. if self.windows.state == 99:
  122. raise "用户主动取消"
  123. @classmethod
  124. def get_temp_pic_info(cls, root):
  125. """
  126. 获取详情页模板中的信息
  127. """
  128. main_pic_list = []
  129. mask_pic_list = []
  130. if os.path.exists(r"{}\main_image".format(root)):
  131. for _name in os.listdir(r"{}\main_image".format(root)):
  132. _path = r"{}\main_image\{}".format(root, _name)
  133. if os.path.isdir(_path):
  134. main_pic_list.append([x["file_path"] for x in get_images(_path)])
  135. mask_pic_list.append(
  136. [x["file_path"] for x in get_image_mask(_path)]
  137. )
  138. _l = get_images(r"{}\show".format(root))
  139. temp_pic_path = _l[0]["file_path"] if _l else None
  140. other_pic_list = [x["file_path"] for x in get_images(r"{}".format(root))]
  141. return {
  142. "main_pic_path_list": main_pic_list,
  143. "temp_pic_path": temp_pic_path,
  144. "mask_pic_list": mask_pic_list,
  145. "other_pic_path_list": other_pic_list,
  146. }
  147. def init(self):
  148. for goods_art_no_value in self.goods_no_value["货号资料"]:
  149. self.data[goods_art_no_value["货号"]] = {"pics": goods_art_no_value["pics"],
  150. "pic_is_deal": {}
  151. }
  152. def get_text_value(self, key, subsection_len=0):
  153. text = ""
  154. if key in self.goods_no_value:
  155. if self.goods_no_value[key]:
  156. text = str(self.goods_no_value[key])
  157. text = text.replace(r"\n", "\n")
  158. if key in ["跟高", "鞋宽", "帮高", "脚掌围", "鞋长"]:
  159. if text:
  160. text = text.split(".")[0]
  161. if subsection_len != 0:
  162. text = text.split("\n")
  163. text = [x for x in text if x]
  164. if len(text) == 2:
  165. text_1 = text[0]
  166. text_2 = text[1]
  167. return text_1, text_2
  168. else:
  169. if text:
  170. text_1 = text[0]
  171. else:
  172. text_1 = ""
  173. text_2 = ""
  174. return text_1, text_2
  175. return text
  176. def create_folder(self, path):
  177. if not os.path.exists(path):
  178. os.makedirs(path)
  179. def get_all_process_pics(self):
  180. """
  181. 获取所有颜色的过程图片
  182. data = [
  183. {"货号": "",
  184. "素材": [{
  185. "名称": "俯视",
  186. "抠图": "路径1",
  187. "阴影": "路径2"
  188. }, ]},
  189. ]
  190. """
  191. return_data = []
  192. for goods_art_no in self.data:
  193. goods_art_no_dict = {"货号": goods_art_no,
  194. "素材": [],
  195. }
  196. # 图片数据重新排序
  197. pic_data = []
  198. for pic_name, pic_path in self.data[goods_art_no]["pics"].items():
  199. root_path, file_name = os.path.split(pic_path)
  200. pic_data.append(file_name)
  201. pic_data = natsorted(pic_data, alg=ns.PATH)
  202. for file_name in pic_data:
  203. if "阴影" in file_name:
  204. _, action_name, _ = file_name.split("_")
  205. pic_path = self.data[goods_art_no]["pics"]["{}-阴影".format(action_name)]
  206. pic_cutout_path = self.data[goods_art_no]["pics"]["{}-抠图".format(action_name)]
  207. if os.path.exists(pic_path) and os.path.exists(pic_cutout_path):
  208. goods_art_no_dict["素材"].append({"名称": action_name, "抠图": pic_cutout_path, "阴影": pic_path})
  209. return_data.append(goods_art_no_dict)
  210. return return_data
  211. def get_overlay_pic_from_dict(self, goods_art_no, color_name, bg_color) -> PictureProcessing:
  212. self.check_state_end()
  213. # 增加逻辑,获取任意货号下的组合图
  214. if "组合" in color_name:
  215. goods_art_no, color_name = self.get_all_scene_list(goods_art_no, color_name)
  216. key = "{}-{}-{}".format(goods_art_no, color_name, bg_color)
  217. if key in self.overlay_pic_dict:
  218. return self.overlay_pic_dict[key]
  219. if goods_art_no in self.data:
  220. for pic_name, pic_path in self.data[goods_art_no]["pics"].items():
  221. if "阴影" in pic_name:
  222. action_name = pic_name.replace("-阴影", "")
  223. if action_name == color_name:
  224. pp1 = PictureProcessing(pic_path)
  225. pp2 = PictureProcessing(self.data[goods_art_no]["pics"]["{}-抠图".format(action_name)])
  226. pp1 = pp1.get_overlay_pic(top_img=pp2, color=bg_color).resize(mode="pixel", base="width",
  227. value=1600)
  228. self.overlay_pic_dict[key] = pp1
  229. if key in self.overlay_pic_dict:
  230. return self.overlay_pic_dict[key]
  231. def image_init(self, bg_color=(246, 246, 246)):
  232. # 制作一批素材图,添加背景色,并保留阴影,以及处理成最小尺寸
  233. for goods_art_no in self.data:
  234. for pic_name, pic_path in self.data[goods_art_no]["pics"].items():
  235. if "阴影" in pic_name:
  236. action_name = pic_name.replace("-阴影", "")
  237. pp1 = PictureProcessing(pic_path)
  238. pp2 = PictureProcessing(self.data[goods_art_no]["pics"]["{}-抠图".format(action_name)])
  239. pp1 = pp1.get_overlay_pic(top_img=pp2, color=bg_color).resize(mode="pixel", base="width",
  240. value=1600)
  241. self.data[goods_art_no]["pic_is_deal"][action_name] = pp1
  242. # 获取任意货号的场景图,优先取指定货号;
  243. # 调整,按顺序从货号列表中提取所有组合图
  244. def get_all_scene_info(self, goods_art_no):
  245. data = []
  246. # 收集所有组合图
  247. # 找任意一个有组合图的货号
  248. for goods_art_no_dict in self.goods_no_value["货号资料"]:
  249. _goods_art_no = goods_art_no_dict["货号"]
  250. _view_name_list = set([x.split("-")[0] for x in goods_art_no_dict["pics"]])
  251. for _view_name in _view_name_list:
  252. if "组合" not in _view_name:
  253. continue
  254. return _goods_art_no
  255. return goods_art_no
  256. def get_all_scene_list(self, goods_art_no, view_name: str):
  257. if "组合" == view_name:
  258. view_name = "组合1"
  259. try:
  260. view_index = int(view_name.replace("组合", "")) - 1
  261. except:
  262. return goods_art_no, "无法匹配"
  263. data = []
  264. # 收集所有组合图
  265. # 找任意一个有组合图的货号
  266. for goods_art_no_dict in self.goods_no_value["货号资料"]:
  267. _goods_art_no = goods_art_no_dict["货号"]
  268. _view_name_list = set([x.split("-")[0] for x in goods_art_no_dict["pics"]])
  269. for _view_name in _view_name_list:
  270. if "组合" not in _view_name:
  271. continue
  272. data.append(
  273. {"goods_art_no": _goods_art_no,
  274. "view_name": _view_name
  275. }
  276. )
  277. if len(data) <= view_index:
  278. return goods_art_no, "无法匹配"
  279. else:
  280. return data[view_index]["goods_art_no"], data[view_index]["view_name"]
  281. def image_one_pic(self, goods_art_no, name, bg_color=None, return_orign=None):
  282. # 增加逻辑,获取任意货号下的组合图
  283. if "组合" in name:
  284. goods_art_no, name = self.get_all_scene_list(goods_art_no, name)
  285. print("324 goods_art_no, name", goods_art_no, name)
  286. # 制作一批素材图,添加背景色,并保留阴影,以及处理成最小尺寸
  287. for pic_name, pic_path in self.data[goods_art_no]["pics"].items():
  288. if "阴影" in pic_name:
  289. action_name = pic_name.replace("-阴影", "")
  290. if name != action_name:
  291. continue
  292. pp1 = PictureProcessing(pic_path)
  293. pp2 = PictureProcessing(self.data[goods_art_no]["pics"]["{}-抠图".format(action_name)])
  294. if not return_orign:
  295. pp1 = pp1.get_overlay_pic(top_img=pp2, color=bg_color).resize(mode="pixel", base="width",
  296. value=1600)
  297. return pp1
  298. else:
  299. return pp1, pp2
  300. if not return_orign:
  301. return None
  302. else:
  303. return None, None
  304. def move_other_pic(self, move_main_pic=True):
  305. # ------------------------------移动其他图片------------------------------
  306. goods_no_main_pic_number = 0
  307. for goods_art_no_dict in self.goods_no_value["货号资料"]:
  308. if "800x800" not in goods_art_no_dict:
  309. continue
  310. if not goods_art_no_dict["800x800"]:
  311. continue
  312. goods_art_no = ""
  313. if "编号" in goods_art_no_dict:
  314. if goods_art_no_dict["编号"]:
  315. goods_art_no = goods_art_no_dict["编号"]
  316. if not goods_art_no:
  317. goods_art_no = goods_art_no_dict["货号"]
  318. # print("goods_art_no:", goods_art_no)
  319. # 移动颜色图=====================
  320. goods_art_no_f = "{}/{}/{}".format(self.out_put_dir, self.goods_no, goods_art_no)
  321. self.create_folder(goods_art_no_f)
  322. # 放入一张主图
  323. old_pic_path_1 = goods_art_no_dict["800x800"][0]
  324. shutil.copy(old_pic_path_1,
  325. "{}/{}{}".format(goods_art_no_f, goods_art_no, os.path.splitext(old_pic_path_1)[1]))
  326. # 把其他主图放入作为款号图=====================
  327. if move_main_pic:
  328. for pic_path in goods_art_no_dict["800x800"]:
  329. goods_no_main_pic_number += 1
  330. e = os.path.splitext(pic_path)[1]
  331. shutil.copy(pic_path,
  332. "{out_put_dir}/{goods_no}/{goods_no}({goods_no_main_pic_number}){e}".format(
  333. out_put_dir=self.out_put_dir, goods_no=self.goods_no,
  334. goods_no_main_pic_number=str(goods_no_main_pic_number + 10).zfill(2),
  335. e=e))
  336. def deal_all_main_pic(self):
  337. """
  338. 处理主图模板,如存在出图模板则进行对应处理
  339. """
  340. # 获取主图模板列表
  341. all_main_pic_path_list = DetailBase.get_temp_pic_info(root=self.root)["main_pic_path_list"]
  342. if not all_main_pic_path_list:
  343. return
  344. mask_pic_list = DetailBase.get_temp_pic_info(root=self.root)["mask_pic_list"]
  345. data = self.get_all_process_pics()
  346. print("========deal_all_main_pic=========主图相关素材:")
  347. view_list = ["组合", "组合2", "组合3", "组合4", "组合5", "组合6", "俯视", "侧视", "后跟", "鞋底", "内里", ]
  348. for _index, main_pic_path_list in enumerate(all_main_pic_path_list):
  349. self.check_state_end()
  350. out_path_root = "{out_put_dir}/{goods_no}/main_image_{_index}".format(
  351. out_put_dir=self.out_put_dir,
  352. goods_no=self.goods_no,
  353. _index=_index
  354. )
  355. check_path(out_path_root)
  356. if mask_pic_list[_index]:
  357. mask_pic = mask_pic_list[_index][0]
  358. else:
  359. mask_pic = None
  360. goods_no_main_pic_number = 10
  361. # g_index 为第几个颜色货号
  362. for g_index, goods_art_no_dict in enumerate(data):
  363. goods_art_no = goods_art_no_dict["货号"]
  364. # =====================重新指定=================================
  365. _material_sort_dict = {}
  366. for index, material_dict in enumerate(goods_art_no_dict["素材"]):
  367. name = material_dict["名称"]
  368. _material_sort_dict[name] = material_dict
  369. # ======================================================
  370. file_name_index = -1
  371. for view_name in view_list:
  372. # 组合图比较特殊,为全局获取
  373. if g_index != 0:
  374. if "组合" in view_name:
  375. continue
  376. if view_name not in _material_sort_dict:
  377. continue
  378. self.check_state_end()
  379. pp_jpg, pp_png = self.image_one_pic(goods_art_no, view_name, bg_color=None, return_orign=True)
  380. if not pp_jpg:
  381. continue
  382. file_name_index += 1
  383. # 获取对应主图模板
  384. if len(main_pic_path_list) < file_name_index + 1:
  385. main_pic_path = main_pic_path_list[-1]
  386. else:
  387. main_pic_path = main_pic_path_list[file_name_index]
  388. pp_bg = PictureProcessing(main_pic_path)
  389. original_width = pp_bg.width
  390. if original_width != 1600:
  391. pp_bg = pp_bg.resize(value=1600)
  392. if mask_pic:
  393. mask_bg = PictureProcessing(mask_pic)
  394. mask_bg = mask_bg.resize(value=1600)
  395. mask_box_im = mask_bg.get_im()
  396. box_size = mask_box_im.getbbox()
  397. result_image = mask_box_im.crop(box_size)
  398. mask_width, mask_height = result_image.size
  399. mask_x, mask_y = box_size[0], box_size[1]
  400. else:
  401. mask_width, mask_height = pp_bg.size
  402. mask_width, mask_height = int(mask_width * 12 / 16), int(mask_height * 12 / 16)
  403. mask_x, mask_y = int((pp_bg.size[0] - mask_width) / 2), int((pp_bg.size[1] - mask_height) / 2)
  404. if view_name != "后跟":
  405. pp_jpg = pp_jpg.resize(base_by_box=(mask_width, mask_height))
  406. pp_png = pp_png.resize(base_by_box=(mask_width, mask_height))
  407. # 计算粘贴的位置 mask的位置+图片在mask中的位置
  408. p_x = mask_x + int((mask_width - pp_jpg.width) / 2)
  409. p_y = mask_y + int((mask_height - pp_jpg.height) / 2)
  410. pp_bg = pp_bg.to_overlay_pic_advance(mode="pixel", top_img=pp_jpg, base="nw",
  411. value=(p_x, p_y), top_png_img=pp_png)
  412. else:
  413. new_mask_width, new_mask_height = int(mask_width / 1.6), int(mask_height / 1.6)
  414. pp_jpg = pp_jpg.resize(base_by_box=(new_mask_width, new_mask_height))
  415. pp_png = pp_png.resize(base_by_box=(new_mask_width, new_mask_height))
  416. new_mask_x = int((mask_width - new_mask_width) / 2 + mask_x)
  417. new_mask_y = int((mask_height - new_mask_height) / 2 + mask_y)
  418. # 计算粘贴的位置 mask的位置+图片在mask中的位置
  419. p_x = new_mask_x + int((new_mask_width - pp_jpg.width) / 2)
  420. p_y = new_mask_y + int((new_mask_height - pp_jpg.height) / 2)
  421. pp_bg = pp_bg.to_overlay_pic_advance(mode="pixel", top_img=pp_jpg, base="nw", value=(p_x, p_y),
  422. top_png_img=pp_png)
  423. goods_no_main_pic_number += 1
  424. out_pic_path = "{out_path_root}/{goods_no}({goods_no_main_pic_number}){pic_mode}".format(
  425. out_path_root=out_path_root,
  426. goods_no=self.goods_no,
  427. goods_no_main_pic_number=goods_no_main_pic_number,
  428. pic_mode=settings.OUT_PIC_MODE,
  429. )
  430. if settings.OUT_PIC_FACTOR > 1.0:
  431. print("图片锐化处理")
  432. pp_bg = pp_bg.sharpen_image(factor=settings.OUT_PIC_FACTOR)
  433. if original_width < 1600:
  434. pp_bg = pp_bg.resize(value=original_width)
  435. print("392 out_pic_path", out_pic_path)
  436. if settings.OUT_PIC_MODE == ".jpg":
  437. pp_bg.save_as_rgb(out_pic_path)
  438. else:
  439. pp_bg.save_as_png(out_pic_path)
  440. def add_pic(self, detailed_images):
  441. self.check_state_end()
  442. todo_detailed_images = []
  443. detailed_images = [x for x in detailed_images if x]
  444. if not detailed_images:
  445. return
  446. for i in detailed_images:
  447. if isinstance(i, list):
  448. for n in i:
  449. todo_detailed_images.append(n)
  450. else:
  451. todo_detailed_images.append(i)
  452. page_len = 0
  453. for index, pp in enumerate(todo_detailed_images):
  454. page_len += pp.height
  455. bg_im = Image.new("RGB", (pp.width, page_len), (255, 255, 255))
  456. n = 0
  457. for index, pp in enumerate(todo_detailed_images):
  458. bg_im.paste(pp.im, (0, n))
  459. n += pp.height
  460. return bg_im
  461. # 通用方法,用于写文字
  462. def add_text_list(self, text_list, spacing=5, base="wn", base_width=1600):
  463. text_list = [x for x in text_list if x["text"]]
  464. # print(text_list)
  465. # spacing 行间距
  466. text_image_list = []
  467. max_w = 0
  468. total_h = 0
  469. for text_data in text_list:
  470. _pp = PictureProcessing("RGBA", (base_width, 1200), (255, 255, 255, 0))
  471. if base == "wn" or base == "nw":
  472. align = "left"
  473. anchor = None
  474. value = (0, 250)
  475. if base == "cn" or base == "nc":
  476. align = "center"
  477. anchor = "mm"
  478. value = (int(base_width / 2), 250)
  479. if base == "en" or base == "ne":
  480. align = "right"
  481. anchor = "rs"
  482. value = (base_width - 10, 250)
  483. _pp = _pp.get_text_image_advanced(
  484. value=value,
  485. font=text_data["font"],
  486. text=text_data["text"],
  487. align=align,
  488. anchor=anchor,
  489. spacing=5,
  490. fill=text_data["fill"],
  491. return_mode="min_image",
  492. margins=(0, 0, 0, 0)
  493. )
  494. text_image_list.append(_pp)
  495. if _pp.width > max_w:
  496. max_w = _pp.width
  497. total_h += _pp.height
  498. if "spacing" in text_data:
  499. total_h += text_data["spacing"]
  500. if not text_image_list:
  501. return None
  502. #
  503. bg = PictureProcessing("RGBA", (max_w, total_h * 3), (0, 0, 0, 0))
  504. y = 0
  505. for text_image, text_data in zip(text_image_list, text_list):
  506. bg = bg.paste_img(top_img=text_image, value=(0, y), base=base)
  507. y += spacing + text_image.height
  508. if "spacing" in text_data:
  509. y += text_data["spacing"]
  510. bg = bg.crop(mode="min")
  511. # _ = bg.paste_img_invert(top_img=PictureProcessing("RGB", (bg.width,bg.height), (255, 255, 255)))
  512. # _.show()
  513. return bg
  514. def generate_font_list_to_pic(self):
  515. font_path_list = [r"resources\ttf\puhui\Bold.ttf",
  516. r"resources\ttf\puhui\Medium.ttf",
  517. r"resources\ttf\puhui\Heavy.ttf",
  518. r"resources\ttf\puhui\Light.ttf",
  519. r"resources\ttf\puhui\Regular.ttf",
  520. ]
  521. text_v_list = [
  522. "这是一段话Bold",
  523. "这是一段话Medium",
  524. "这是一段话Heavy",
  525. "这是一段话Light",
  526. "这是一段话Regular",
  527. ]
  528. detailed_images = []
  529. for font_path, text in zip(font_path_list, text_v_list):
  530. text_list = []
  531. for size in range(26, 80, 2):
  532. font = ImageFont.truetype(font_path, size)
  533. text_list.append({"text": "{}-字号{}".format(text, size),
  534. "font": font,
  535. "fill": (110, 110, 110),
  536. })
  537. text_image = self.add_text_list(text_list, spacing=15, base="nw")
  538. text_image = text_image.crop(mode="min")
  539. text_image = text_image.paste_img_invert(top_img=PictureProcessing("RGB", text_image.size, (255, 255, 255)))
  540. detailed_images.append(text_image)
  541. return PictureProcessing(im=self.add_pic(detailed_images))
  542. # 图片分段,每段至少大于N长度
  543. def pp_pic_subsection(self, pp: PictureProcessing, one_height=3200):
  544. total_height = pp.height
  545. now_height = 0
  546. detailed_images = []
  547. while 1:
  548. if now_height + one_height < total_height:
  549. h1 = now_height
  550. h2 = now_height + one_height
  551. bbox = (0, h1, pp.width, h2)
  552. # print("bbox1", bbox)
  553. detailed_images.append(pp.crop(bbox=bbox))
  554. now_height = now_height + one_height
  555. continue
  556. if now_height + one_height >= total_height:
  557. h1 = now_height
  558. h2 = total_height
  559. bbox = (0, h1, pp.width, h2)
  560. # print("bbox2", bbox)
  561. detailed_images.append(pp.crop(bbox=bbox))
  562. break
  563. return detailed_images