goods_detail_pics.py 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. """
  2. 步骤:
  3. 1、整理需要处理的款号图-输出款号图文件夹
  4. 2、整理所有相关的图片作为素材图
  5. 3、按要求进行拼接
  6. """
  7. import cv2
  8. import numpy as np
  9. from PIL import Image, ImageFont
  10. import os
  11. import settings
  12. from module.base_mode.image_pic_deal import OnePicDeal
  13. from collections import defaultdict
  14. from module.view_control.generate_goods_no_detail_pic.detail_generate_base import DetailBase
  15. from module.view_control.generate_goods_no_detail_pic.pic_deal import PictureProcessing
  16. class DetailPicGet备份(DetailBase):
  17. def __init__(self, goods_no, goods_no_value: dict, out_put_dir, ):
  18. super().__init__(goods_no, goods_no_value, out_put_dir)
  19. self.goods_no = goods_no
  20. self.out_put_dir = out_put_dir
  21. self.goods_no_value = goods_no_value
  22. self.data = {}
  23. for goods_art_no_value in goods_no_value["货号资料"]:
  24. self.data[goods_art_no_value["货号"]] = {}
  25. for pic_name, pic_path in goods_art_no_value["pics"].items():
  26. pic_name = pic_name.replace("俯视图", "俯视")
  27. pic_name = pic_name.replace("侧视图", "侧视")
  28. pic_name = pic_name.replace("后跟图", "后跟")
  29. pic_name = pic_name.replace("鞋底图", "鞋底")
  30. pic_name = pic_name.replace("内里图", "内里")
  31. print(pic_name)
  32. self.data[goods_art_no_value["货号"]][pic_name] = pic_path
  33. self.run()
  34. pass
  35. def to_resize(self, _im, width=None, high=None):
  36. _im_x, _im_y = _im.size
  37. if width and high:
  38. if _im_x >= _im_y:
  39. high = None
  40. else:
  41. width = None
  42. if width:
  43. re_x = int(width)
  44. re_y = int(_im_y * re_x / _im_x)
  45. else:
  46. re_y = int(high)
  47. re_x = int(_im_x * re_y / _im_y)
  48. _im = _im.resize((re_x, re_y))
  49. return _im
  50. def image_init(self):
  51. name_size_dict = {"俯视": 1600,
  52. "侧视": 1600,
  53. "后跟": 800,
  54. "鞋底": 1600,
  55. "内里": 1600,
  56. }
  57. # 制作一批素材图,添加背景色,并保留阴影,以及处理成最小尺寸
  58. bg_color = (246, 246, 246)
  59. for _goods_art_no, value in self.data.items():
  60. name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
  61. for _name in name_list:
  62. # 打开第一张图
  63. im1 = Image.open(self.data[_goods_art_no]["{name}-阴影".format(name=_name)])
  64. im2 = Image.open(self.data[_goods_art_no]["{name}-抠图".format(name=_name)])
  65. im = self.get_overlay_pic(im1, im2, bg_color)
  66. im = self.to_resize(im, width=name_size_dict[_name])
  67. # 保留最小区域
  68. # im = self.get_goods_pos(im, im2)
  69. self.data[_goods_art_no][_name] = im
  70. def run(self):
  71. self.image_init()
  72. bg_color = (246, 246, 246)
  73. detailed_images = []
  74. """ 制作主图 """
  75. goods_art_no_list = list(self.data.keys())
  76. # if len(goods_art_no_list) > 1:
  77. # im_1 = self.data[goods_art_no_list[0]]["侧视"]
  78. # im_2 = self.data[goods_art_no_list[1]]["俯视"]
  79. # else:
  80. im_1 = self.data[goods_art_no_list[0]]["侧视"]
  81. im_2 = self.data[goods_art_no_list[0]]["俯视"]
  82. data = []
  83. data.append({"command": "resize",
  84. "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  85. "base_im": {"im": Image.new("RGB", (550, 340), (248, 248, 248))}, # 参考基于其他图 PIL格式
  86. "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  87. "value": 0, # 固定值,如果为百分比,则为0
  88. "percentage": 0, })
  89. image = self.deal_one_pic(img=im_1, data=data)
  90. data = []
  91. data.append({
  92. "command": "paste_img",
  93. "img": {"im": image},
  94. "pos": {"plugins_mode": "pixel", # pixel
  95. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  96. "value": (0, 0),
  97. "percentage": (0, 0),
  98. },
  99. "margins": (0, 0, 0, 0), # 上下左右边距
  100. })
  101. image = self.deal_one_pic(img=Image.new("RGB", (550, 340), bg_color), data=data)
  102. data = []
  103. bg_img = Image.open(r"resources\detail_image_2\image (1).jpg")
  104. data.append({
  105. "command": "paste_img",
  106. "img": {"im": image},
  107. "pos": {"plugins_mode": "pixel", # pixel
  108. "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
  109. "value": (26, 263),
  110. "percentage": (0, 0),
  111. },
  112. "margins": (0, 0, 0, 0), # 上下左右边距
  113. })
  114. bg_img = self.deal_one_pic(img=bg_img, data=data)
  115. # ---------- 第二张图处理
  116. data = []
  117. data.append({"command": "resize",
  118. "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  119. "base_im": {"im": Image.new("RGB", (550, 340), (248, 248, 248))}, # 参考基于其他图 PIL格式
  120. "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  121. "value": 0, # 固定值,如果为百分比,则为0
  122. "percentage": 0, }) # 百分比
  123. image = self.deal_one_pic(img=im_2, data=data)
  124. data = []
  125. data.append({
  126. "command": "paste_img",
  127. "img": {"im": image},
  128. "pos": {"plugins_mode": "pixel", # pixel
  129. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  130. "value": (0, 0),
  131. "percentage": (0, 0),
  132. },
  133. "margins": (0, 0, 0, 0), # 上下左右边距
  134. })
  135. image = self.deal_one_pic(img=Image.new("RGB", (550, 340), bg_color), data=data)
  136. data = []
  137. data.append({
  138. "command": "paste_img",
  139. "img": {"im": image},
  140. "pos": {"plugins_mode": "pixel", # pixel
  141. "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
  142. "value": (26, 626),
  143. "percentage": (0, 0),
  144. },
  145. "margins": (0, 0, 0, 0), # 上下左右边距
  146. })
  147. font = ImageFont.truetype(r'resources\ttf\simhei.ttf', 30)
  148. _d = [("商品款号", self.goods_no_value["款号"], 700, 297),
  149. ("商品面料", self.goods_no_value["商品面料"], 700, 380),
  150. ("商品内里", self.goods_no_value["商品内里"], 700, 469),
  151. ("商品鞋底", self.goods_no_value["商品鞋底"], 700, 549),
  152. ("后帮高", self.goods_no_value["后帮高"], 700, 667),
  153. ("前掌宽", self.goods_no_value["前掌宽"], 700, 751),
  154. ("鞋跟高", self.goods_no_value["鞋跟高"], 700, 828), ]
  155. for i in _d:
  156. if i[1]:
  157. data.append({
  158. "command": "add_text",
  159. "pos": {"plugins_mode": "pixel", # pixel relative
  160. "value": (i[2], i[3]), },
  161. "font": font,
  162. "text": "{}:{}".format(i[0], i[1]),
  163. "align": "center",
  164. "direction": "",
  165. "max_len_one_line": "",
  166. "spacing": 10,
  167. "fill": (17, 16, 16),
  168. })
  169. image = self.deal_one_pic(img=bg_img, data=data)
  170. detailed_images.append(image)
  171. """ 设计师说展示图 """
  172. # 设计师说
  173. text = self.goods_no_value["FAB说明"]
  174. if text:
  175. detailed_images.append(Image.open(r"resources\detail_image_2\image (2).jpg"))
  176. data = []
  177. text = text.replace(r"\n", "\n")
  178. _ = text.split("\n")
  179. bg_img = Image.new("RGB", (1200, len(_) * 100 + 30), (255, 255, 255))
  180. data.append({
  181. "command": "add_text",
  182. "pos": {"plugins_mode": "pixel", # pixel relative
  183. "value": (600, 50), },
  184. "font": font,
  185. "text": text,
  186. "anchor": "ma",
  187. "align": "center",
  188. "direction": "",
  189. "max_len_one_line": "",
  190. "spacing": 50,
  191. "fill": (83, 83, 83),
  192. })
  193. image = self.deal_one_pic(img=bg_img, data=data)
  194. detailed_images.append(image)
  195. # image.show()
  196. # raise 1
  197. """ 制作角度展示图 """
  198. # 角度展示
  199. detailed_images.append(Image.open(r"resources\detail_image_2\image (3).jpg"))
  200. goods_art_no_list = list(self.data.keys())
  201. for index, goods_art_no in enumerate(goods_art_no_list):
  202. if index == 0:
  203. name_list = ["侧视", "俯视", "后跟", "鞋底"]
  204. else:
  205. name_list = ["侧视", "俯视", ]
  206. for _name in name_list:
  207. # 处理图片,需要粘贴到背景等处理
  208. _image = self.data[goods_art_no][_name]
  209. data = []
  210. data.append({"command": "resize",
  211. "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  212. "base": "width",
  213. # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  214. "value": 649 if _name == "后跟" else 1058, # 固定值,如果为百分比,则为0
  215. }) # 百分比
  216. _image = self.deal_one_pic(img=_image, data=data)
  217. data = []
  218. data.append({
  219. "command": "paste_img",
  220. "img": {"im": _image},
  221. "pos": {"plugins_mode": "pixel", # pixel
  222. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  223. "value": (0, 0),
  224. "percentage": (0, 0),
  225. },
  226. "margins": (0, 0, 0, 0), # 上下左右边距
  227. })
  228. bg_img = Image.new("RGB", (1200, int(_image.height + 50)), bg_color)
  229. _image = self.deal_one_pic(img=bg_img, data=data)
  230. # _image.show()
  231. detailed_images.append(_image)
  232. detailed_images.append(Image.new("RGB", (1200, 50), (255, 255, 255)))
  233. """ 制作详细图 """
  234. detailed_images.append(Image.open(r"resources\detail_image_2\image (4).jpg"))
  235. views = ["俯视", "内里", "后跟", "鞋底"]
  236. goods_art_no = list(self.data.keys())[0]
  237. for view in views:
  238. to_paste_img = self.data[goods_art_no][view]
  239. data = []
  240. # 单图缩放处理
  241. data.append({"command": "resize",
  242. "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  243. "base_im": {"im": ""}, # 参考基于其他图 PIL格式
  244. "base": "width", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  245. "value": 1300 if view == "后跟" else 2200, # 固定值,如果为百分比,则为0
  246. "percentage": 0, }) # 百分比
  247. view_dict = {"俯视": (0, 0, 1100, 1200),
  248. "内里": (-1, -100, 1100, 1200),
  249. "后跟": (0, -100, 1100, 1200),
  250. "鞋底": (0, -100, 1100, 1200),
  251. }
  252. data.append({
  253. "command": "crop_img",
  254. "img": "",
  255. "pos": {"plugins_mode": "pixel", # pixel
  256. "base": "sw", # nw,nc,ne,ec ... 各个方向参考点
  257. "value": view_dict[view],
  258. },
  259. "color_fill": bg_color,
  260. })
  261. # 处理圆角
  262. data.append({"command": "radius", # radius
  263. "plugins_mode": "relative", # pixel 相对(短边),或绝对像素
  264. "circular_pos": (1, 0, 0, 1), # 从左上角顺时针,记录圆角数量
  265. "value": 100, # 固定值,如果为百分比,则为0
  266. "percentage": 0, }) # 百分比
  267. to_paste_img = self.deal_one_pic(to_paste_img, data)
  268. # print(to_paste_img.size)
  269. # 粘贴到白底图上
  270. img = Image.new("RGB", (1200, 1316), (255, 255, 255))
  271. data = []
  272. data.append({
  273. "command": "paste_img",
  274. "img": {"im": to_paste_img},
  275. "pos": {"plugins_mode": "pixel", # pixel relative
  276. "base": "wc", # nw,nc,ne,ec,... 各个方向参考点
  277. "value": (100, 0),
  278. "percentage": "",
  279. },
  280. "margins": (0, 0, 0, 0), # 上下左右边距
  281. })
  282. img = self.deal_one_pic(img, data)
  283. # if view == "后跟":
  284. # img.show()
  285. detailed_images.append(img)
  286. detailed_images.append(Image.open(r"resources\detail_image_2\image (5).jpg"))
  287. output_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  288. self.create_folder(output_path)
  289. for index, im in enumerate(detailed_images):
  290. im.save("{}/{}({}).png".format(output_path, self.goods_no, str(index + 11).zfill(2)))
  291. # img = self.add_pic(detailed_images)
  292. # img.save("{}/0_{}_拼接图.png".format(self.out_put_dir, self.goods_no))
  293. return True
  294. def add_pic(self, detailed_images):
  295. if not detailed_images:
  296. return
  297. page_len = 0
  298. for index, im in enumerate(detailed_images):
  299. page_len += im.height
  300. bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))
  301. n = 0
  302. for index, im in enumerate(detailed_images):
  303. bg_im.paste(im, (0, n))
  304. n += im.height
  305. # bg_im.show()
  306. return bg_im
  307. def get_goods_pos(self, im, cut_image):
  308. # 保留多余内容
  309. old_x, old_y = im.size
  310. x1, y1, x2, y2 = cut_image.getbbox()
  311. goods_w, goods_h = x2 - x1, y2 - y1
  312. _w, _h = int(goods_w / 10), int(goods_h / 10) # 上下左右扩展位置
  313. new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h # 防止超限
  314. new_x1 = 0 if new_x1 < 0 else new_x1
  315. new_y1 = 0 if new_y1 < 0 else new_y1
  316. new_x2 = old_x if new_x2 > old_x else new_x2
  317. new_y2 = old_y if new_y2 > old_y else new_y2
  318. # 剪切掉多余的内容,保留阴影
  319. im = im.crop((new_x1, new_y1, new_x2, new_y2)) # 切图
  320. return im
  321. def set_dict(self, one_dict):
  322. _ = defaultdict(str)
  323. for i, v in one_dict.items():
  324. if isinstance(v, dict):
  325. v = self.set_dict(v)
  326. _[i] = v
  327. return _
  328. def deal_one_pic(self, img: Image, data=None):
  329. """
  330. 通用图片处理器
  331. 1、基于某原始图,进行加工,包括粘贴、单图处理等逻辑
  332. """
  333. data = [self.set_dict(x) for x in data]
  334. for command in data:
  335. if command["command"] == "resize":
  336. img = OnePicDeal().resize(img, command)
  337. continue
  338. if command["command"] == "paste_img":
  339. img = OnePicDeal().paste_img(img, command)
  340. continue
  341. if command["command"] == "crop_img":
  342. img = OnePicDeal().crop_img(img, command)
  343. continue
  344. if command["command"] == "radius":
  345. img = OnePicDeal().radius(img, command)
  346. continue
  347. if command["command"] == "add_text":
  348. img = OnePicDeal().add_text(img, command)
  349. continue
  350. return img
  351. def get_overlay_pic(self, pil_img_1, pil_img_2, color):
  352. im_w, im_h = pil_img_1.size
  353. cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)
  354. # 创建一张纯色底图
  355. image_white = Image.new("RGB", (im_w, im_h), color)
  356. cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
  357. new_im = self.to_color_2(cv_image_white, cv_im)
  358. # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
  359. # new_im = cv2.add(new_im, cv_im_2)
  360. new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
  361. new_im.paste(pil_img_2, (0, 0), pil_img_2)
  362. return new_im
  363. def to_color_2(self, target, blend): # 正片叠底
  364. return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)
  365. def to_color_1(self, img1, img2): # PS颜色模式
  366. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
  367. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
  368. img2[:, :, 0] = img1[:, :, 0]
  369. img2[:, :, 1] = img1[:, :, 1]
  370. res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
  371. return res
  372. class DetailPicGetHqt(DetailBase):
  373. def __init__(self, goods_no, goods_no_value: dict, out_put_dir, ):
  374. super().__init__(goods_no, goods_no_value, out_put_dir)
  375. def run(self):
  376. bg_color = (246, 246, 246)
  377. self.image_init(bg_color)
  378. detailed_images = []
  379. """ 制作主图 """
  380. goods_art_no_list = list(self.data.keys())
  381. # if len(goods_art_no_list) > 1:
  382. # im_1 = self.data[goods_art_no_list[0]]["侧视"]
  383. # im_2 = self.data[goods_art_no_list[1]]["俯视"]
  384. # else:
  385. pp_1 = self.data[goods_art_no_list[0]]["pic_is_deal"]["侧视"]
  386. pp_2 = self.data[goods_art_no_list[0]]["pic_is_deal"]["俯视"]
  387. pp_image = pp_1.resize(mode="relative",
  388. base="by_im",
  389. value=0,
  390. base_im=PictureProcessing("RGB", (550, 340), (248, 248, 248)),
  391. percentage=0)
  392. pp_image = PictureProcessing("RGB", (550, 340), bg_color).paste_img(
  393. mode="pixel", top_img=pp_image, base="center"
  394. )
  395. pp_image = PictureProcessing("RGB", (550, 340), bg_color).paste_img(
  396. mode="pixel", top_img=pp_image, base="nw",value= (26, 263),
  397. )
  398. bg_img = PictureProcessing(r"resources\detail_image_2\image (1).jpg").paste_img(
  399. mode="pixel", top_img=pp_image, base="nw",value= (26, 263))
  400. bg_img.show()
  401. return
  402. # ---------- 第二张图处理
  403. data = []
  404. data.append({"command": "resize",
  405. "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  406. "base_im": {"im": Image.new("RGB", (550, 340), (248, 248, 248))}, # 参考基于其他图 PIL格式
  407. "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  408. "value": 0, # 固定值,如果为百分比,则为0
  409. "percentage": 0, }) # 百分比
  410. image = self.deal_one_pic(img=im_2, data=data)
  411. data = []
  412. data.append({
  413. "command": "paste_img",
  414. "img": {"im": image},
  415. "pos": {"plugins_mode": "pixel", # pixel
  416. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  417. "value": (0, 0),
  418. "percentage": (0, 0),
  419. },
  420. "margins": (0, 0, 0, 0), # 上下左右边距
  421. })
  422. image = self.deal_one_pic(img=Image.new("RGB", (550, 340), bg_color), data=data)
  423. data = []
  424. data.append({
  425. "command": "paste_img",
  426. "img": {"im": image},
  427. "pos": {"plugins_mode": "pixel", # pixel
  428. "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
  429. "value": (26, 626),
  430. "percentage": (0, 0),
  431. },
  432. "margins": (0, 0, 0, 0), # 上下左右边距
  433. })
  434. font = ImageFont.truetype(r'resources\ttf\simhei.ttf', 30)
  435. _d = [("商品款号", self.goods_no_value["款号"], 700, 297),
  436. ("商品面料", self.goods_no_value["商品面料"], 700, 380),
  437. ("商品内里", self.goods_no_value["商品内里"], 700, 469),
  438. ("商品鞋底", self.goods_no_value["商品鞋底"], 700, 549),
  439. ("后帮高", self.goods_no_value["后帮高"], 700, 667),
  440. ("前掌宽", self.goods_no_value["前掌宽"], 700, 751),
  441. ("鞋跟高", self.goods_no_value["鞋跟高"], 700, 828), ]
  442. for i in _d:
  443. if i[1]:
  444. data.append({
  445. "command": "add_text",
  446. "pos": {"plugins_mode": "pixel", # pixel relative
  447. "value": (i[2], i[3]), },
  448. "font": font,
  449. "text": "{}:{}".format(i[0], i[1]),
  450. "align": "center",
  451. "direction": "",
  452. "max_len_one_line": "",
  453. "spacing": 10,
  454. "fill": (17, 16, 16),
  455. })
  456. image = self.deal_one_pic(img=bg_img, data=data)
  457. detailed_images.append(image)
  458. """ 设计师说展示图 """
  459. # 设计师说
  460. text = self.goods_no_value["FAB说明"]
  461. if text:
  462. detailed_images.append(Image.open(r"resources\detail_image_2\image (2).jpg"))
  463. data = []
  464. text = text.replace(r"\n", "\n")
  465. _ = text.split("\n")
  466. bg_img = Image.new("RGB", (1200, len(_) * 100 + 30), (255, 255, 255))
  467. data.append({
  468. "command": "add_text",
  469. "pos": {"plugins_mode": "pixel", # pixel relative
  470. "value": (600, 50), },
  471. "font": font,
  472. "text": text,
  473. "anchor": "ma",
  474. "align": "center",
  475. "direction": "",
  476. "max_len_one_line": "",
  477. "spacing": 50,
  478. "fill": (83, 83, 83),
  479. })
  480. image = self.deal_one_pic(img=bg_img, data=data)
  481. detailed_images.append(image)
  482. # image.show()
  483. # raise 1
  484. """ 制作角度展示图 """
  485. # 角度展示
  486. detailed_images.append(Image.open(r"resources\detail_image_2\image (3).jpg"))
  487. goods_art_no_list = list(self.data.keys())
  488. for index, goods_art_no in enumerate(goods_art_no_list):
  489. if index == 0:
  490. name_list = ["侧视", "俯视", "后跟", "鞋底"]
  491. else:
  492. name_list = ["侧视", "俯视", ]
  493. for _name in name_list:
  494. # 处理图片,需要粘贴到背景等处理
  495. _image = self.data[goods_art_no][_name]
  496. data = []
  497. data.append({"command": "resize",
  498. "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  499. "base": "width",
  500. # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  501. "value": 649 if _name == "后跟" else 1058, # 固定值,如果为百分比,则为0
  502. }) # 百分比
  503. _image = self.deal_one_pic(img=_image, data=data)
  504. data = []
  505. data.append({
  506. "command": "paste_img",
  507. "img": {"im": _image},
  508. "pos": {"plugins_mode": "pixel", # pixel
  509. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  510. "value": (0, 0),
  511. "percentage": (0, 0),
  512. },
  513. "margins": (0, 0, 0, 0), # 上下左右边距
  514. })
  515. bg_img = Image.new("RGB", (1200, int(_image.height + 50)), bg_color)
  516. _image = self.deal_one_pic(img=bg_img, data=data)
  517. # _image.show()
  518. detailed_images.append(_image)
  519. detailed_images.append(Image.new("RGB", (1200, 50), (255, 255, 255)))
  520. """ 制作详细图 """
  521. detailed_images.append(Image.open(r"resources\detail_image_2\image (4).jpg"))
  522. views = ["俯视", "内里", "后跟", "鞋底"]
  523. goods_art_no = list(self.data.keys())[0]
  524. for view in views:
  525. to_paste_img = self.data[goods_art_no][view]
  526. data = []
  527. # 单图缩放处理
  528. data.append({"command": "resize",
  529. "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  530. "base_im": {"im": ""}, # 参考基于其他图 PIL格式
  531. "base": "width", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  532. "value": 1300 if view == "后跟" else 2200, # 固定值,如果为百分比,则为0
  533. "percentage": 0, }) # 百分比
  534. view_dict = {"俯视": (0, 0, 1100, 1200),
  535. "内里": (-1, -100, 1100, 1200),
  536. "后跟": (0, -100, 1100, 1200),
  537. "鞋底": (0, -100, 1100, 1200),
  538. }
  539. data.append({
  540. "command": "crop_img",
  541. "img": "",
  542. "pos": {"plugins_mode": "pixel", # pixel
  543. "base": "sw", # nw,nc,ne,ec ... 各个方向参考点
  544. "value": view_dict[view],
  545. },
  546. "color_fill": bg_color,
  547. })
  548. # 处理圆角
  549. data.append({"command": "radius", # radius
  550. "plugins_mode": "relative", # pixel 相对(短边),或绝对像素
  551. "circular_pos": (1, 0, 0, 1), # 从左上角顺时针,记录圆角数量
  552. "value": 100, # 固定值,如果为百分比,则为0
  553. "percentage": 0, }) # 百分比
  554. to_paste_img = self.deal_one_pic(to_paste_img, data)
  555. # print(to_paste_img.size)
  556. # 粘贴到白底图上
  557. img = Image.new("RGB", (1200, 1316), (255, 255, 255))
  558. data = []
  559. data.append({
  560. "command": "paste_img",
  561. "img": {"im": to_paste_img},
  562. "pos": {"plugins_mode": "pixel", # pixel relative
  563. "base": "wc", # nw,nc,ne,ec,... 各个方向参考点
  564. "value": (100, 0),
  565. "percentage": "",
  566. },
  567. "margins": (0, 0, 0, 0), # 上下左右边距
  568. })
  569. img = self.deal_one_pic(img, data)
  570. # if view == "后跟":
  571. # img.show()
  572. detailed_images.append(img)
  573. detailed_images.append(Image.open(r"resources\detail_image_2\image (5).jpg"))
  574. output_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  575. self.create_folder(output_path)
  576. for index, im in enumerate(detailed_images):
  577. im.save("{}/{}({}).png".format(output_path, self.goods_no, str(index + 11).zfill(2)))
  578. # img = self.add_pic(detailed_images)
  579. # img.save("{}/0_{}_拼接图.png".format(self.out_put_dir, self.goods_no))
  580. return True
  581. def add_pic(self, detailed_images):
  582. if not detailed_images:
  583. return
  584. page_len = 0
  585. for index, im in enumerate(detailed_images):
  586. page_len += im.height
  587. bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))
  588. n = 0
  589. for index, im in enumerate(detailed_images):
  590. bg_im.paste(im, (0, n))
  591. n += im.height
  592. # bg_im.show()
  593. return bg_im
  594. def get_goods_pos(self, im, cut_image):
  595. # 保留多余内容
  596. old_x, old_y = im.size
  597. x1, y1, x2, y2 = cut_image.getbbox()
  598. goods_w, goods_h = x2 - x1, y2 - y1
  599. _w, _h = int(goods_w / 10), int(goods_h / 10) # 上下左右扩展位置
  600. new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h # 防止超限
  601. new_x1 = 0 if new_x1 < 0 else new_x1
  602. new_y1 = 0 if new_y1 < 0 else new_y1
  603. new_x2 = old_x if new_x2 > old_x else new_x2
  604. new_y2 = old_y if new_y2 > old_y else new_y2
  605. # 剪切掉多余的内容,保留阴影
  606. im = im.crop((new_x1, new_y1, new_x2, new_y2)) # 切图
  607. return im
  608. def set_dict(self, one_dict):
  609. _ = defaultdict(str)
  610. for i, v in one_dict.items():
  611. if isinstance(v, dict):
  612. v = self.set_dict(v)
  613. _[i] = v
  614. return _
  615. def deal_one_pic(self, img: Image, data=None):
  616. """
  617. 通用图片处理器
  618. 1、基于某原始图,进行加工,包括粘贴、单图处理等逻辑
  619. """
  620. data = [self.set_dict(x) for x in data]
  621. for command in data:
  622. if command["command"] == "resize":
  623. img = OnePicDeal().resize(img, command)
  624. continue
  625. if command["command"] == "paste_img":
  626. img = OnePicDeal().paste_img(img, command)
  627. continue
  628. if command["command"] == "crop_img":
  629. img = OnePicDeal().crop_img(img, command)
  630. continue
  631. if command["command"] == "radius":
  632. img = OnePicDeal().radius(img, command)
  633. continue
  634. if command["command"] == "add_text":
  635. img = OnePicDeal().add_text(img, command)
  636. continue
  637. return img
  638. def get_overlay_pic(self, pil_img_1, pil_img_2, color):
  639. im_w, im_h = pil_img_1.size
  640. cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)
  641. # 创建一张纯色底图
  642. image_white = Image.new("RGB", (im_w, im_h), color)
  643. cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
  644. new_im = self.to_color_2(cv_image_white, cv_im)
  645. # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
  646. # new_im = cv2.add(new_im, cv_im_2)
  647. new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
  648. new_im.paste(pil_img_2, (0, 0), pil_img_2)
  649. return new_im
  650. def to_color_2(self, target, blend): # 正片叠底
  651. return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)
  652. def to_color_1(self, img1, img2): # PS颜色模式
  653. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
  654. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
  655. img2[:, :, 0] = img1[:, :, 0]
  656. img2[:, :, 1] = img1[:, :, 1]
  657. res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
  658. return res
  659. class DetailPicGetHLM(object):
  660. def __init__(self, goods_no, goods_no_value: dict, out_put_dir, windows=None):
  661. self.windows = windows
  662. self.goods_no = goods_no
  663. self.out_put_dir = out_put_dir
  664. self.goods_no_value = goods_no_value
  665. self.data = {}
  666. for goods_art_no_value in goods_no_value["货号资料"]:
  667. self.data[goods_art_no_value["货号"]] = {}
  668. for pic_name, pic_path in goods_art_no_value["pics"].items():
  669. self.data[goods_art_no_value["货号"]][pic_name] = pic_path
  670. self.run()
  671. pass
  672. def to_resize(self, _im, width=None, high=None):
  673. _im_x, _im_y = _im.size
  674. if width and high:
  675. if _im_x >= _im_y:
  676. high = None
  677. else:
  678. width = None
  679. if width:
  680. re_x = int(width)
  681. re_y = int(_im_y * re_x / _im_x)
  682. else:
  683. re_y = int(high)
  684. re_x = int(_im_x * re_y / _im_y)
  685. _im = _im.resize((re_x, re_y))
  686. return _im
  687. def image_init(self):
  688. name_size_dict = {"俯视": 1600,
  689. "侧视": 1600,
  690. "后跟": 800,
  691. "鞋底": 1600,
  692. "内里": 1600,
  693. }
  694. # 制作一批素材图,添加背景色,并保留阴影,以及处理成最小尺寸
  695. bg_color = (246, 246, 246)
  696. for _goods_art_no, value in self.data.items():
  697. if settings.PROJECT == "红蜻蜓":
  698. name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
  699. elif settings.PROJECT == "惠利玛":
  700. name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
  701. else:
  702. name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
  703. for _name in name_list:
  704. # 打开第一张图
  705. try:
  706. im1 = Image.open(self.data[_goods_art_no]["{name}-阴影".format(name=_name)])
  707. im2 = Image.open(self.data[_goods_art_no]["{name}-抠图".format(name=_name)])
  708. im = self.get_overlay_pic(im1, im2, bg_color)
  709. im = self.to_resize(im, width=name_size_dict[_name])
  710. # 保留最小区域
  711. # im = self.get_goods_pos(im, im2)
  712. self.data[_goods_art_no][_name] = im
  713. except BaseException as e:
  714. print(e)
  715. pass
  716. def run(self):
  717. self.image_init()
  718. bg_color = (246, 246, 246)
  719. detailed_images = []
  720. """ 头部信息 """
  721. detailed_images.append(Image.open(r"resources\detail_image_3\image (1).jpg"))
  722. """ 制作主图 """
  723. goods_art_no_list = list(self.data.keys())
  724. im_1 = self.data[goods_art_no_list[0]]["俯视"]
  725. im_2 = self.data[goods_art_no_list[0]]["侧视"]
  726. data = []
  727. data.append({"command": "resize",
  728. "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  729. "base_im": {"im": Image.new("RGB", (604, 418), (248, 248, 248))}, # 参考基于其他图 PIL格式
  730. "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  731. "value": 0, # 固定值,如果为百分比,则为0
  732. "percentage": 0, })
  733. image = self.deal_one_pic(img=im_1, data=data)
  734. data = []
  735. data.append({
  736. "command": "paste_img",
  737. "img": {"im": image},
  738. "pos": {"plugins_mode": "pixel", # pixel
  739. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  740. "value": (0, 0),
  741. "percentage": (0, 0),
  742. },
  743. "margins": (0, 0, 0, 0), # 上下左右边距
  744. })
  745. image = self.deal_one_pic(img=Image.new("RGB", (604, 418), bg_color), data=data)
  746. data = []
  747. bg_img = Image.new("RGB", (1200, 918), (255, 255, 255))
  748. data.append({
  749. "command": "paste_img",
  750. "img": {"im": image},
  751. "pos": {"plugins_mode": "pixel", # pixel
  752. "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
  753. "value": (26, 26),
  754. "percentage": (0, 0),
  755. },
  756. "margins": (0, 0, 0, 0), # 上下左右边距
  757. })
  758. bg_img = self.deal_one_pic(img=bg_img, data=data)
  759. # ---------- 第二张图处理
  760. data = []
  761. data.append({"command": "resize",
  762. "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  763. "base_im": {"im": Image.new("RGB", (604, 418), (248, 248, 248))}, # 参考基于其他图 PIL格式
  764. "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  765. "value": 0, # 固定值,如果为百分比,则为0
  766. "percentage": 0, }) # 百分比
  767. image = self.deal_one_pic(img=im_2, data=data)
  768. data = []
  769. data.append({
  770. "command": "paste_img",
  771. "img": {"im": image},
  772. "pos": {"plugins_mode": "pixel", # pixel
  773. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  774. "value": (0, 0),
  775. "percentage": (0, 0),
  776. },
  777. "margins": (0, 0, 0, 0), # 上下左右边距
  778. })
  779. image = self.deal_one_pic(img=Image.new("RGB", (604, 418), bg_color), data=data)
  780. data = []
  781. data.append({
  782. "command": "paste_img",
  783. "img": {"im": image},
  784. "pos": {"plugins_mode": "pixel", # pixel
  785. "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
  786. "value": (26, 26 + 26 + 418),
  787. "percentage": (0, 0),
  788. },
  789. "margins": (0, 0, 0, 0), # 上下左右边距
  790. })
  791. font = ImageFont.truetype(r'resources\ttf\simhei.ttf', 30)
  792. _d = [("款号", self.goods_no_value["款号"], 722, 26),
  793. ("面料", self.goods_no_value["商品面料"], 722, 106),
  794. ("内里", self.goods_no_value["商品内里"], 722, 186),
  795. ("鞋底", self.goods_no_value["商品鞋底"], 722, 266), ]
  796. for i in _d:
  797. if i[1]:
  798. data.append({
  799. "command": "add_text",
  800. "pos": {"plugins_mode": "pixel", # pixel relative
  801. "value": (i[2], i[3]), },
  802. "font": font,
  803. "text": "{}:{}".format(i[0], i[1]),
  804. "align": "center",
  805. "direction": "",
  806. "max_len_one_line": "",
  807. "spacing": 10,
  808. "fill": (17, 16, 16),
  809. })
  810. image = self.deal_one_pic(img=bg_img, data=data)
  811. detailed_images.append(image)
  812. """ 尺码表 """
  813. detailed_images.append(Image.open(r"resources\detail_image_3\image (2).jpg"))
  814. """ 细节图展示 """
  815. view_dict = {"俯视": {"crop_img_value": (0, 0, 1086, 752),
  816. "crop_img_base": "sw",
  817. "paste_img_value": (0, 0),
  818. "paste_img_base": "center",
  819. },
  820. "侧视": {"crop_img_value": (888, 0, 1086, 752),
  821. "crop_img_base": "sw",
  822. "paste_img_value": (0, 0),
  823. "paste_img_base": "center",
  824. },
  825. }
  826. goods_art_no = list(self.data.keys())[0]
  827. for view in view_dict:
  828. to_paste_img = self.data[goods_art_no][view]
  829. data = []
  830. # 单图缩放处理
  831. data.append({"command": "resize",
  832. "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  833. "base_im": {"im": ""}, # 参考基于其他图 PIL格式
  834. "base": "width", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  835. "value": 1800, # 固定值,如果为百分比,则为0
  836. "percentage": 0, }) # 百分比
  837. data.append({
  838. "command": "crop_img",
  839. "img": "",
  840. "pos": {"plugins_mode": "pixel", # pixel
  841. "base": view_dict[view]["crop_img_base"], # nw,nc,ne,ec ... 各个方向参考点
  842. "value": view_dict[view]["crop_img_value"],
  843. },
  844. "color_fill": bg_color,
  845. })
  846. # 处理圆角
  847. data.append({"command": "radius", # radius
  848. "plugins_mode": "relative", # pixel 相对(短边),或绝对像素
  849. "circular_pos": (1, 1, 1, 1), # 从左上角顺时针,记录圆角数量
  850. "value": 100, # 固定值,如果为百分比,则为0
  851. "percentage": 0, }) # 百分比
  852. to_paste_img = self.deal_one_pic(to_paste_img, data)
  853. # 粘贴到白底图上
  854. data = []
  855. data.append({
  856. "command": "paste_img",
  857. "img": {"im": to_paste_img},
  858. "pos": {"plugins_mode": "pixel", # pixel
  859. "base": view_dict[view]["paste_img_base"], # nw,nc,ne,ec ... 各个方向参考点
  860. "value": view_dict[view]["paste_img_value"],
  861. },
  862. "color_fill": bg_color,
  863. })
  864. bg_c = Image.new("RGB", (1200, 848), (255, 255, 255))
  865. bg_c_img = self.deal_one_pic(bg_c, data)
  866. to_paste_img = self.deal_one_pic(bg_c_img, data)
  867. detailed_images.append(to_paste_img)
  868. """ 制作角度展示图 """
  869. # 角度展示
  870. goods_art_no_list = list(self.data.keys())
  871. for index, goods_art_no in enumerate(goods_art_no_list):
  872. if index == 0:
  873. name_list = ["俯视", "侧视", "后跟", "鞋底"]
  874. else:
  875. name_list = ["俯视", ]
  876. for _name in name_list:
  877. # 处理图片,需要粘贴到背景等处理
  878. if _name not in self.data[goods_art_no]:
  879. continue
  880. _image = self.data[goods_art_no][_name]
  881. data = []
  882. data.append({"command": "resize",
  883. "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
  884. "base": "width",
  885. # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
  886. "value": 500 if _name == "后跟" else 1058, # 固定值,如果为百分比,则为0
  887. }) # 百分比
  888. _image = self.deal_one_pic(img=_image, data=data)
  889. data = []
  890. data.append({
  891. "command": "paste_img",
  892. "img": {"im": _image},
  893. "pos": {"plugins_mode": "pixel", # pixel
  894. "base": "center", # nw,nc,ne,ec ... 各个方向参考点
  895. "value": (0, 0),
  896. "percentage": (0, 0),
  897. },
  898. "margins": (0, 0, 0, 0), # 上下左右边距
  899. })
  900. bg_img = Image.new("RGB", (1200, int(_image.height + 50)), bg_color)
  901. _image = self.deal_one_pic(img=bg_img, data=data)
  902. # _image.show()
  903. detailed_images.append(_image)
  904. detailed_images.append(Image.new("RGB", (1200, 50), (255, 255, 255)))
  905. detailed_images.append(Image.open(r"resources\detail_image_3\image (3).jpg"))
  906. """ 制作详细图 """
  907. output_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
  908. self.create_folder(output_path)
  909. for index, im in enumerate(detailed_images):
  910. im.save("{}/{}({}).png".format(output_path, self.goods_no, str(index + 11).zfill(2)))
  911. img = self.add_pic(detailed_images)
  912. img.save("{}/0_{}_拼接图.png".format(self.out_put_dir, self.goods_no))
  913. return True
  914. def create_folder(self, path):
  915. def check_folder(__path):
  916. if not os.path.exists(__path):
  917. os.makedirs(__path)
  918. return False
  919. return True
  920. # 文件夹不存在,创建货号子集文件夹
  921. if not check_folder(path):
  922. pass
  923. # for name in ["原始图", "原始图_已抠图", "800x800", "200images"]:
  924. # other_path = path + "/" + name
  925. # check_folder(other_path)
  926. def add_pic(self, detailed_images):
  927. if not detailed_images:
  928. return
  929. page_len = 0
  930. for index, im in enumerate(detailed_images):
  931. page_len += im.height
  932. bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))
  933. n = 0
  934. for index, im in enumerate(detailed_images):
  935. bg_im.paste(im, (0, n))
  936. n += im.height
  937. # bg_im.show()
  938. return bg_im
  939. def get_goods_pos(self, im, cut_image):
  940. # 保留多余内容
  941. old_x, old_y = im.size
  942. x1, y1, x2, y2 = cut_image.getbbox()
  943. goods_w, goods_h = x2 - x1, y2 - y1
  944. _w, _h = int(goods_w / 10), int(goods_h / 10) # 上下左右扩展位置
  945. new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h # 防止超限
  946. new_x1 = 0 if new_x1 < 0 else new_x1
  947. new_y1 = 0 if new_y1 < 0 else new_y1
  948. new_x2 = old_x if new_x2 > old_x else new_x2
  949. new_y2 = old_y if new_y2 > old_y else new_y2
  950. # 剪切掉多余的内容,保留阴影
  951. im = im.crop((new_x1, new_y1, new_x2, new_y2)) # 切图
  952. return im
  953. def set_dict(self, one_dict):
  954. _ = defaultdict(str)
  955. for i, v in one_dict.items():
  956. if isinstance(v, dict):
  957. v = self.set_dict(v)
  958. _[i] = v
  959. return _
  960. def deal_one_pic(self, img: Image, data=None):
  961. """
  962. 通用图片处理器
  963. 1、基于某原始图,进行加工,包括粘贴、单图处理等逻辑
  964. """
  965. data = [self.set_dict(x) for x in data]
  966. for command in data:
  967. if command["command"] == "resize":
  968. img = OnePicDeal().resize(img, command)
  969. continue
  970. if command["command"] == "paste_img":
  971. img = OnePicDeal().paste_img(img, command)
  972. continue
  973. if command["command"] == "crop_img":
  974. img = OnePicDeal().crop_img(img, command)
  975. continue
  976. if command["command"] == "radius":
  977. img = OnePicDeal().radius(img, command)
  978. continue
  979. if command["command"] == "add_text":
  980. img = OnePicDeal().add_text(img, command)
  981. continue
  982. return img
  983. def get_overlay_pic(self, pil_img_1, pil_img_2, color):
  984. im_w, im_h = pil_img_1.size
  985. cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)
  986. # 创建一张纯色底图
  987. image_white = Image.new("RGB", (im_w, im_h), color)
  988. cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
  989. new_im = self.to_color_2(cv_image_white, cv_im)
  990. # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
  991. # new_im = cv2.add(new_im, cv_im_2)
  992. new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
  993. new_im.paste(pil_img_2, (0, 0), pil_img_2)
  994. return new_im
  995. def to_color_2(self, target, blend): # 正片叠底
  996. return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)
  997. def to_color_1(self, img1, img2): # PS颜色模式
  998. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
  999. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
  1000. img2[:, :, 0] = img1[:, :, 0]
  1001. img2[:, :, 1] = img1[:, :, 1]
  1002. res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
  1003. return res
  1004. if __name__ == '__main__':
  1005. _path = r"D:\MyDocuments\PythonCode\MyPython\red_dragonfly\deal_pics\auto_capture\IPC\output\2023-11-06"
  1006. goods_no_dict = {}
  1007. for goods_art_no in os.listdir(_path):
  1008. if not os.path.isdir("{}/{}".format(_path, goods_art_no)):
  1009. continue
  1010. if len(goods_art_no) < 10:
  1011. print("{}--长度异常".format(goods_art_no))
  1012. continue
  1013. # print(goods_art_no)
  1014. goods_no = goods_art_no[:9]
  1015. if goods_no not in goods_no_dict:
  1016. goods_no_dict[goods_no] = {}
  1017. goods_no_dict[goods_no][goods_art_no] = {}
  1018. # 获取该货号下所有素材图 阴影图处理
  1019. source_material_path = "{}/{}/阴影图处理".format(_path, goods_art_no)
  1020. if not os.path.exists(source_material_path):
  1021. print("{}--缺少 阴影图处理 文件夹".format(goods_art_no))
  1022. continue
  1023. _ = {}
  1024. if len(os.listdir(source_material_path)) % 2 != 0:
  1025. print("{}--阴影图处理 文件错误".format(goods_art_no))
  1026. continue
  1027. name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
  1028. for pic in os.listdir(source_material_path):
  1029. # print(pic)
  1030. _pic = pic.replace(".png", "")
  1031. _pic = _pic.split("_")
  1032. if len(_pic) != 3:
  1033. continue
  1034. _["{}-{}".format(_pic[1], _pic[2])] = "{}/{}".format(source_material_path, pic)
  1035. goods_no_dict[goods_no][goods_art_no] = _
  1036. # print(_)
  1037. # 准备拼接处理
  1038. for goods_no, goods_no_value in goods_no_dict.items():
  1039. # if goods_no == "AC5200054":
  1040. print("开始处理-----{}".format(goods_no))
  1041. GenerateDetailPic(goods_no, goods_no_value)
  1042. # raise 1
  1043. # print(goods_no_dict)