| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177 |
- """
- 步骤:
- 1、整理需要处理的款号图-输出款号图文件夹
- 2、整理所有相关的图片作为素材图
- 3、按要求进行拼接
- """
- import cv2
- import numpy as np
- from PIL import Image, ImageFont
- import os
- import settings
- from module.base_mode.image_pic_deal import OnePicDeal
- from collections import defaultdict
- from module.view_control.generate_goods_no_detail_pic.detail_generate_base import DetailBase
- from module.view_control.generate_goods_no_detail_pic.pic_deal import PictureProcessing
- class DetailPicGet备份(DetailBase):
- def __init__(self, goods_no, goods_no_value: dict, out_put_dir, ):
- super().__init__(goods_no, goods_no_value, out_put_dir)
- self.goods_no = goods_no
- self.out_put_dir = out_put_dir
- self.goods_no_value = goods_no_value
- self.data = {}
- for goods_art_no_value in goods_no_value["货号资料"]:
- self.data[goods_art_no_value["货号"]] = {}
- for pic_name, pic_path in goods_art_no_value["pics"].items():
- pic_name = pic_name.replace("俯视图", "俯视")
- pic_name = pic_name.replace("侧视图", "侧视")
- pic_name = pic_name.replace("后跟图", "后跟")
- pic_name = pic_name.replace("鞋底图", "鞋底")
- pic_name = pic_name.replace("内里图", "内里")
- print(pic_name)
- self.data[goods_art_no_value["货号"]][pic_name] = pic_path
- self.run()
- pass
- def to_resize(self, _im, width=None, high=None):
- _im_x, _im_y = _im.size
- if width and high:
- if _im_x >= _im_y:
- high = None
- else:
- width = None
- if width:
- re_x = int(width)
- re_y = int(_im_y * re_x / _im_x)
- else:
- re_y = int(high)
- re_x = int(_im_x * re_y / _im_y)
- _im = _im.resize((re_x, re_y))
- return _im
- def image_init(self):
- name_size_dict = {"俯视": 1600,
- "侧视": 1600,
- "后跟": 800,
- "鞋底": 1600,
- "内里": 1600,
- }
- # 制作一批素材图,添加背景色,并保留阴影,以及处理成最小尺寸
- bg_color = (246, 246, 246)
- for _goods_art_no, value in self.data.items():
- name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
- for _name in name_list:
- # 打开第一张图
- im1 = Image.open(self.data[_goods_art_no]["{name}-阴影".format(name=_name)])
- im2 = Image.open(self.data[_goods_art_no]["{name}-抠图".format(name=_name)])
- im = self.get_overlay_pic(im1, im2, bg_color)
- im = self.to_resize(im, width=name_size_dict[_name])
- # 保留最小区域
- # im = self.get_goods_pos(im, im2)
- self.data[_goods_art_no][_name] = im
- def run(self):
- self.image_init()
- bg_color = (246, 246, 246)
- detailed_images = []
- """ 制作主图 """
- goods_art_no_list = list(self.data.keys())
- # if len(goods_art_no_list) > 1:
- # im_1 = self.data[goods_art_no_list[0]]["侧视"]
- # im_2 = self.data[goods_art_no_list[1]]["俯视"]
- # else:
- im_1 = self.data[goods_art_no_list[0]]["侧视"]
- im_2 = self.data[goods_art_no_list[0]]["俯视"]
- data = []
- data.append({"command": "resize",
- "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": Image.new("RGB", (550, 340), (248, 248, 248))}, # 参考基于其他图 PIL格式
- "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 0, # 固定值,如果为百分比,则为0
- "percentage": 0, })
- image = self.deal_one_pic(img=im_1, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- image = self.deal_one_pic(img=Image.new("RGB", (550, 340), bg_color), data=data)
- data = []
- bg_img = Image.open(r"resources\detail_image_2\image (1).jpg")
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
- "value": (26, 263),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- bg_img = self.deal_one_pic(img=bg_img, data=data)
- # ---------- 第二张图处理
- data = []
- data.append({"command": "resize",
- "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": Image.new("RGB", (550, 340), (248, 248, 248))}, # 参考基于其他图 PIL格式
- "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 0, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- image = self.deal_one_pic(img=im_2, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- image = self.deal_one_pic(img=Image.new("RGB", (550, 340), bg_color), data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
- "value": (26, 626),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- font = ImageFont.truetype(r'resources\ttf\simhei.ttf', 30)
- _d = [("商品款号", self.goods_no_value["款号"], 700, 297),
- ("商品面料", self.goods_no_value["商品面料"], 700, 380),
- ("商品内里", self.goods_no_value["商品内里"], 700, 469),
- ("商品鞋底", self.goods_no_value["商品鞋底"], 700, 549),
- ("后帮高", self.goods_no_value["后帮高"], 700, 667),
- ("前掌宽", self.goods_no_value["前掌宽"], 700, 751),
- ("鞋跟高", self.goods_no_value["鞋跟高"], 700, 828), ]
- for i in _d:
- if i[1]:
- data.append({
- "command": "add_text",
- "pos": {"plugins_mode": "pixel", # pixel relative
- "value": (i[2], i[3]), },
- "font": font,
- "text": "{}:{}".format(i[0], i[1]),
- "align": "center",
- "direction": "",
- "max_len_one_line": "",
- "spacing": 10,
- "fill": (17, 16, 16),
- })
- image = self.deal_one_pic(img=bg_img, data=data)
- detailed_images.append(image)
- """ 设计师说展示图 """
- # 设计师说
- text = self.goods_no_value["FAB说明"]
- if text:
- detailed_images.append(Image.open(r"resources\detail_image_2\image (2).jpg"))
- data = []
- text = text.replace(r"\n", "\n")
- _ = text.split("\n")
- bg_img = Image.new("RGB", (1200, len(_) * 100 + 30), (255, 255, 255))
- data.append({
- "command": "add_text",
- "pos": {"plugins_mode": "pixel", # pixel relative
- "value": (600, 50), },
- "font": font,
- "text": text,
- "anchor": "ma",
- "align": "center",
- "direction": "",
- "max_len_one_line": "",
- "spacing": 50,
- "fill": (83, 83, 83),
- })
- image = self.deal_one_pic(img=bg_img, data=data)
- detailed_images.append(image)
- # image.show()
- # raise 1
- """ 制作角度展示图 """
- # 角度展示
- detailed_images.append(Image.open(r"resources\detail_image_2\image (3).jpg"))
- goods_art_no_list = list(self.data.keys())
- for index, goods_art_no in enumerate(goods_art_no_list):
- if index == 0:
- name_list = ["侧视", "俯视", "后跟", "鞋底"]
- else:
- name_list = ["侧视", "俯视", ]
- for _name in name_list:
- # 处理图片,需要粘贴到背景等处理
- _image = self.data[goods_art_no][_name]
- data = []
- data.append({"command": "resize",
- "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base": "width",
- # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 649 if _name == "后跟" else 1058, # 固定值,如果为百分比,则为0
- }) # 百分比
- _image = self.deal_one_pic(img=_image, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": _image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- bg_img = Image.new("RGB", (1200, int(_image.height + 50)), bg_color)
- _image = self.deal_one_pic(img=bg_img, data=data)
- # _image.show()
- detailed_images.append(_image)
- detailed_images.append(Image.new("RGB", (1200, 50), (255, 255, 255)))
- """ 制作详细图 """
- detailed_images.append(Image.open(r"resources\detail_image_2\image (4).jpg"))
- views = ["俯视", "内里", "后跟", "鞋底"]
- goods_art_no = list(self.data.keys())[0]
- for view in views:
- to_paste_img = self.data[goods_art_no][view]
- data = []
- # 单图缩放处理
- data.append({"command": "resize",
- "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": ""}, # 参考基于其他图 PIL格式
- "base": "width", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 1300 if view == "后跟" else 2200, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- view_dict = {"俯视": (0, 0, 1100, 1200),
- "内里": (-1, -100, 1100, 1200),
- "后跟": (0, -100, 1100, 1200),
- "鞋底": (0, -100, 1100, 1200),
- }
- data.append({
- "command": "crop_img",
- "img": "",
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "sw", # nw,nc,ne,ec ... 各个方向参考点
- "value": view_dict[view],
- },
- "color_fill": bg_color,
- })
- # 处理圆角
- data.append({"command": "radius", # radius
- "plugins_mode": "relative", # pixel 相对(短边),或绝对像素
- "circular_pos": (1, 0, 0, 1), # 从左上角顺时针,记录圆角数量
- "value": 100, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- to_paste_img = self.deal_one_pic(to_paste_img, data)
- # print(to_paste_img.size)
- # 粘贴到白底图上
- img = Image.new("RGB", (1200, 1316), (255, 255, 255))
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": to_paste_img},
- "pos": {"plugins_mode": "pixel", # pixel relative
- "base": "wc", # nw,nc,ne,ec,... 各个方向参考点
- "value": (100, 0),
- "percentage": "",
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- img = self.deal_one_pic(img, data)
- # if view == "后跟":
- # img.show()
- detailed_images.append(img)
- detailed_images.append(Image.open(r"resources\detail_image_2\image (5).jpg"))
- output_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
- self.create_folder(output_path)
- for index, im in enumerate(detailed_images):
- im.save("{}/{}({}).png".format(output_path, self.goods_no, str(index + 11).zfill(2)))
- # img = self.add_pic(detailed_images)
- # img.save("{}/0_{}_拼接图.png".format(self.out_put_dir, self.goods_no))
- return True
- def add_pic(self, detailed_images):
- if not detailed_images:
- return
- page_len = 0
- for index, im in enumerate(detailed_images):
- page_len += im.height
- bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))
- n = 0
- for index, im in enumerate(detailed_images):
- bg_im.paste(im, (0, n))
- n += im.height
- # bg_im.show()
- return bg_im
- def get_goods_pos(self, im, cut_image):
- # 保留多余内容
- old_x, old_y = im.size
- x1, y1, x2, y2 = cut_image.getbbox()
- goods_w, goods_h = x2 - x1, y2 - y1
- _w, _h = int(goods_w / 10), int(goods_h / 10) # 上下左右扩展位置
- new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h # 防止超限
- new_x1 = 0 if new_x1 < 0 else new_x1
- new_y1 = 0 if new_y1 < 0 else new_y1
- new_x2 = old_x if new_x2 > old_x else new_x2
- new_y2 = old_y if new_y2 > old_y else new_y2
- # 剪切掉多余的内容,保留阴影
- im = im.crop((new_x1, new_y1, new_x2, new_y2)) # 切图
- return im
- def set_dict(self, one_dict):
- _ = defaultdict(str)
- for i, v in one_dict.items():
- if isinstance(v, dict):
- v = self.set_dict(v)
- _[i] = v
- return _
- def deal_one_pic(self, img: Image, data=None):
- """
- 通用图片处理器
- 1、基于某原始图,进行加工,包括粘贴、单图处理等逻辑
- """
- data = [self.set_dict(x) for x in data]
- for command in data:
- if command["command"] == "resize":
- img = OnePicDeal().resize(img, command)
- continue
- if command["command"] == "paste_img":
- img = OnePicDeal().paste_img(img, command)
- continue
- if command["command"] == "crop_img":
- img = OnePicDeal().crop_img(img, command)
- continue
- if command["command"] == "radius":
- img = OnePicDeal().radius(img, command)
- continue
- if command["command"] == "add_text":
- img = OnePicDeal().add_text(img, command)
- continue
- return img
- def get_overlay_pic(self, pil_img_1, pil_img_2, color):
- im_w, im_h = pil_img_1.size
- cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)
- # 创建一张纯色底图
- image_white = Image.new("RGB", (im_w, im_h), color)
- cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
- new_im = self.to_color_2(cv_image_white, cv_im)
- # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
- # new_im = cv2.add(new_im, cv_im_2)
- new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
- new_im.paste(pil_img_2, (0, 0), pil_img_2)
- return new_im
- def to_color_2(self, target, blend): # 正片叠底
- return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)
- def to_color_1(self, img1, img2): # PS颜色模式
- img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
- img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
- img2[:, :, 0] = img1[:, :, 0]
- img2[:, :, 1] = img1[:, :, 1]
- res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
- return res
- class DetailPicGetHqt(DetailBase):
- def __init__(self, goods_no, goods_no_value: dict, out_put_dir, ):
- super().__init__(goods_no, goods_no_value, out_put_dir)
- def run(self):
- bg_color = (246, 246, 246)
- self.image_init(bg_color)
- detailed_images = []
- """ 制作主图 """
- goods_art_no_list = list(self.data.keys())
- # if len(goods_art_no_list) > 1:
- # im_1 = self.data[goods_art_no_list[0]]["侧视"]
- # im_2 = self.data[goods_art_no_list[1]]["俯视"]
- # else:
- pp_1 = self.data[goods_art_no_list[0]]["pic_is_deal"]["侧视"]
- pp_2 = self.data[goods_art_no_list[0]]["pic_is_deal"]["俯视"]
- pp_image = pp_1.resize(mode="relative",
- base="by_im",
- value=0,
- base_im=PictureProcessing("RGB", (550, 340), (248, 248, 248)),
- percentage=0)
- pp_image = PictureProcessing("RGB", (550, 340), bg_color).paste_img(
- mode="pixel", top_img=pp_image, base="center"
- )
- pp_image = PictureProcessing("RGB", (550, 340), bg_color).paste_img(
- mode="pixel", top_img=pp_image, base="nw",value= (26, 263),
- )
- bg_img = PictureProcessing(r"resources\detail_image_2\image (1).jpg").paste_img(
- mode="pixel", top_img=pp_image, base="nw",value= (26, 263))
- bg_img.show()
- return
- # ---------- 第二张图处理
- data = []
- data.append({"command": "resize",
- "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": Image.new("RGB", (550, 340), (248, 248, 248))}, # 参考基于其他图 PIL格式
- "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 0, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- image = self.deal_one_pic(img=im_2, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- image = self.deal_one_pic(img=Image.new("RGB", (550, 340), bg_color), data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
- "value": (26, 626),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- font = ImageFont.truetype(r'resources\ttf\simhei.ttf', 30)
- _d = [("商品款号", self.goods_no_value["款号"], 700, 297),
- ("商品面料", self.goods_no_value["商品面料"], 700, 380),
- ("商品内里", self.goods_no_value["商品内里"], 700, 469),
- ("商品鞋底", self.goods_no_value["商品鞋底"], 700, 549),
- ("后帮高", self.goods_no_value["后帮高"], 700, 667),
- ("前掌宽", self.goods_no_value["前掌宽"], 700, 751),
- ("鞋跟高", self.goods_no_value["鞋跟高"], 700, 828), ]
- for i in _d:
- if i[1]:
- data.append({
- "command": "add_text",
- "pos": {"plugins_mode": "pixel", # pixel relative
- "value": (i[2], i[3]), },
- "font": font,
- "text": "{}:{}".format(i[0], i[1]),
- "align": "center",
- "direction": "",
- "max_len_one_line": "",
- "spacing": 10,
- "fill": (17, 16, 16),
- })
- image = self.deal_one_pic(img=bg_img, data=data)
- detailed_images.append(image)
- """ 设计师说展示图 """
- # 设计师说
- text = self.goods_no_value["FAB说明"]
- if text:
- detailed_images.append(Image.open(r"resources\detail_image_2\image (2).jpg"))
- data = []
- text = text.replace(r"\n", "\n")
- _ = text.split("\n")
- bg_img = Image.new("RGB", (1200, len(_) * 100 + 30), (255, 255, 255))
- data.append({
- "command": "add_text",
- "pos": {"plugins_mode": "pixel", # pixel relative
- "value": (600, 50), },
- "font": font,
- "text": text,
- "anchor": "ma",
- "align": "center",
- "direction": "",
- "max_len_one_line": "",
- "spacing": 50,
- "fill": (83, 83, 83),
- })
- image = self.deal_one_pic(img=bg_img, data=data)
- detailed_images.append(image)
- # image.show()
- # raise 1
- """ 制作角度展示图 """
- # 角度展示
- detailed_images.append(Image.open(r"resources\detail_image_2\image (3).jpg"))
- goods_art_no_list = list(self.data.keys())
- for index, goods_art_no in enumerate(goods_art_no_list):
- if index == 0:
- name_list = ["侧视", "俯视", "后跟", "鞋底"]
- else:
- name_list = ["侧视", "俯视", ]
- for _name in name_list:
- # 处理图片,需要粘贴到背景等处理
- _image = self.data[goods_art_no][_name]
- data = []
- data.append({"command": "resize",
- "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base": "width",
- # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 649 if _name == "后跟" else 1058, # 固定值,如果为百分比,则为0
- }) # 百分比
- _image = self.deal_one_pic(img=_image, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": _image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- bg_img = Image.new("RGB", (1200, int(_image.height + 50)), bg_color)
- _image = self.deal_one_pic(img=bg_img, data=data)
- # _image.show()
- detailed_images.append(_image)
- detailed_images.append(Image.new("RGB", (1200, 50), (255, 255, 255)))
- """ 制作详细图 """
- detailed_images.append(Image.open(r"resources\detail_image_2\image (4).jpg"))
- views = ["俯视", "内里", "后跟", "鞋底"]
- goods_art_no = list(self.data.keys())[0]
- for view in views:
- to_paste_img = self.data[goods_art_no][view]
- data = []
- # 单图缩放处理
- data.append({"command": "resize",
- "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": ""}, # 参考基于其他图 PIL格式
- "base": "width", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 1300 if view == "后跟" else 2200, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- view_dict = {"俯视": (0, 0, 1100, 1200),
- "内里": (-1, -100, 1100, 1200),
- "后跟": (0, -100, 1100, 1200),
- "鞋底": (0, -100, 1100, 1200),
- }
- data.append({
- "command": "crop_img",
- "img": "",
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "sw", # nw,nc,ne,ec ... 各个方向参考点
- "value": view_dict[view],
- },
- "color_fill": bg_color,
- })
- # 处理圆角
- data.append({"command": "radius", # radius
- "plugins_mode": "relative", # pixel 相对(短边),或绝对像素
- "circular_pos": (1, 0, 0, 1), # 从左上角顺时针,记录圆角数量
- "value": 100, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- to_paste_img = self.deal_one_pic(to_paste_img, data)
- # print(to_paste_img.size)
- # 粘贴到白底图上
- img = Image.new("RGB", (1200, 1316), (255, 255, 255))
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": to_paste_img},
- "pos": {"plugins_mode": "pixel", # pixel relative
- "base": "wc", # nw,nc,ne,ec,... 各个方向参考点
- "value": (100, 0),
- "percentage": "",
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- img = self.deal_one_pic(img, data)
- # if view == "后跟":
- # img.show()
- detailed_images.append(img)
- detailed_images.append(Image.open(r"resources\detail_image_2\image (5).jpg"))
- output_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
- self.create_folder(output_path)
- for index, im in enumerate(detailed_images):
- im.save("{}/{}({}).png".format(output_path, self.goods_no, str(index + 11).zfill(2)))
- # img = self.add_pic(detailed_images)
- # img.save("{}/0_{}_拼接图.png".format(self.out_put_dir, self.goods_no))
- return True
- def add_pic(self, detailed_images):
- if not detailed_images:
- return
- page_len = 0
- for index, im in enumerate(detailed_images):
- page_len += im.height
- bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))
- n = 0
- for index, im in enumerate(detailed_images):
- bg_im.paste(im, (0, n))
- n += im.height
- # bg_im.show()
- return bg_im
- def get_goods_pos(self, im, cut_image):
- # 保留多余内容
- old_x, old_y = im.size
- x1, y1, x2, y2 = cut_image.getbbox()
- goods_w, goods_h = x2 - x1, y2 - y1
- _w, _h = int(goods_w / 10), int(goods_h / 10) # 上下左右扩展位置
- new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h # 防止超限
- new_x1 = 0 if new_x1 < 0 else new_x1
- new_y1 = 0 if new_y1 < 0 else new_y1
- new_x2 = old_x if new_x2 > old_x else new_x2
- new_y2 = old_y if new_y2 > old_y else new_y2
- # 剪切掉多余的内容,保留阴影
- im = im.crop((new_x1, new_y1, new_x2, new_y2)) # 切图
- return im
- def set_dict(self, one_dict):
- _ = defaultdict(str)
- for i, v in one_dict.items():
- if isinstance(v, dict):
- v = self.set_dict(v)
- _[i] = v
- return _
- def deal_one_pic(self, img: Image, data=None):
- """
- 通用图片处理器
- 1、基于某原始图,进行加工,包括粘贴、单图处理等逻辑
- """
- data = [self.set_dict(x) for x in data]
- for command in data:
- if command["command"] == "resize":
- img = OnePicDeal().resize(img, command)
- continue
- if command["command"] == "paste_img":
- img = OnePicDeal().paste_img(img, command)
- continue
- if command["command"] == "crop_img":
- img = OnePicDeal().crop_img(img, command)
- continue
- if command["command"] == "radius":
- img = OnePicDeal().radius(img, command)
- continue
- if command["command"] == "add_text":
- img = OnePicDeal().add_text(img, command)
- continue
- return img
- def get_overlay_pic(self, pil_img_1, pil_img_2, color):
- im_w, im_h = pil_img_1.size
- cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)
- # 创建一张纯色底图
- image_white = Image.new("RGB", (im_w, im_h), color)
- cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
- new_im = self.to_color_2(cv_image_white, cv_im)
- # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
- # new_im = cv2.add(new_im, cv_im_2)
- new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
- new_im.paste(pil_img_2, (0, 0), pil_img_2)
- return new_im
- def to_color_2(self, target, blend): # 正片叠底
- return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)
- def to_color_1(self, img1, img2): # PS颜色模式
- img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
- img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
- img2[:, :, 0] = img1[:, :, 0]
- img2[:, :, 1] = img1[:, :, 1]
- res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
- return res
- class DetailPicGetHLM(object):
- def __init__(self, goods_no, goods_no_value: dict, out_put_dir, windows=None):
- self.windows = windows
- self.goods_no = goods_no
- self.out_put_dir = out_put_dir
- self.goods_no_value = goods_no_value
- self.data = {}
- for goods_art_no_value in goods_no_value["货号资料"]:
- self.data[goods_art_no_value["货号"]] = {}
- for pic_name, pic_path in goods_art_no_value["pics"].items():
- self.data[goods_art_no_value["货号"]][pic_name] = pic_path
- self.run()
- pass
- def to_resize(self, _im, width=None, high=None):
- _im_x, _im_y = _im.size
- if width and high:
- if _im_x >= _im_y:
- high = None
- else:
- width = None
- if width:
- re_x = int(width)
- re_y = int(_im_y * re_x / _im_x)
- else:
- re_y = int(high)
- re_x = int(_im_x * re_y / _im_y)
- _im = _im.resize((re_x, re_y))
- return _im
- def image_init(self):
- name_size_dict = {"俯视": 1600,
- "侧视": 1600,
- "后跟": 800,
- "鞋底": 1600,
- "内里": 1600,
- }
- # 制作一批素材图,添加背景色,并保留阴影,以及处理成最小尺寸
- bg_color = (246, 246, 246)
- for _goods_art_no, value in self.data.items():
- if settings.PROJECT == "红蜻蜓":
- name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
- elif settings.PROJECT == "惠利玛":
- name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
- else:
- name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
- for _name in name_list:
- # 打开第一张图
- try:
- im1 = Image.open(self.data[_goods_art_no]["{name}-阴影".format(name=_name)])
- im2 = Image.open(self.data[_goods_art_no]["{name}-抠图".format(name=_name)])
- im = self.get_overlay_pic(im1, im2, bg_color)
- im = self.to_resize(im, width=name_size_dict[_name])
- # 保留最小区域
- # im = self.get_goods_pos(im, im2)
- self.data[_goods_art_no][_name] = im
- except BaseException as e:
- print(e)
- pass
- def run(self):
- self.image_init()
- bg_color = (246, 246, 246)
- detailed_images = []
- """ 头部信息 """
- detailed_images.append(Image.open(r"resources\detail_image_3\image (1).jpg"))
- """ 制作主图 """
- goods_art_no_list = list(self.data.keys())
- im_1 = self.data[goods_art_no_list[0]]["俯视"]
- im_2 = self.data[goods_art_no_list[0]]["侧视"]
- data = []
- data.append({"command": "resize",
- "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": Image.new("RGB", (604, 418), (248, 248, 248))}, # 参考基于其他图 PIL格式
- "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 0, # 固定值,如果为百分比,则为0
- "percentage": 0, })
- image = self.deal_one_pic(img=im_1, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- image = self.deal_one_pic(img=Image.new("RGB", (604, 418), bg_color), data=data)
- data = []
- bg_img = Image.new("RGB", (1200, 918), (255, 255, 255))
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
- "value": (26, 26),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- bg_img = self.deal_one_pic(img=bg_img, data=data)
- # ---------- 第二张图处理
- data = []
- data.append({"command": "resize",
- "plugins_mode": "relative", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": Image.new("RGB", (604, 418), (248, 248, 248))}, # 参考基于其他图 PIL格式
- "base": "by_im", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 0, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- image = self.deal_one_pic(img=im_2, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- image = self.deal_one_pic(img=Image.new("RGB", (604, 418), bg_color), data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "nw", # nw,nc,ne,ec ... 各个方向参考点
- "value": (26, 26 + 26 + 418),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- font = ImageFont.truetype(r'resources\ttf\simhei.ttf', 30)
- _d = [("款号", self.goods_no_value["款号"], 722, 26),
- ("面料", self.goods_no_value["商品面料"], 722, 106),
- ("内里", self.goods_no_value["商品内里"], 722, 186),
- ("鞋底", self.goods_no_value["商品鞋底"], 722, 266), ]
- for i in _d:
- if i[1]:
- data.append({
- "command": "add_text",
- "pos": {"plugins_mode": "pixel", # pixel relative
- "value": (i[2], i[3]), },
- "font": font,
- "text": "{}:{}".format(i[0], i[1]),
- "align": "center",
- "direction": "",
- "max_len_one_line": "",
- "spacing": 10,
- "fill": (17, 16, 16),
- })
- image = self.deal_one_pic(img=bg_img, data=data)
- detailed_images.append(image)
- """ 尺码表 """
- detailed_images.append(Image.open(r"resources\detail_image_3\image (2).jpg"))
- """ 细节图展示 """
- view_dict = {"俯视": {"crop_img_value": (0, 0, 1086, 752),
- "crop_img_base": "sw",
- "paste_img_value": (0, 0),
- "paste_img_base": "center",
- },
- "侧视": {"crop_img_value": (888, 0, 1086, 752),
- "crop_img_base": "sw",
- "paste_img_value": (0, 0),
- "paste_img_base": "center",
- },
- }
- goods_art_no = list(self.data.keys())[0]
- for view in view_dict:
- to_paste_img = self.data[goods_art_no][view]
- data = []
- # 单图缩放处理
- data.append({"command": "resize",
- "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base_im": {"im": ""}, # 参考基于其他图 PIL格式
- "base": "width", # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 1800, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- data.append({
- "command": "crop_img",
- "img": "",
- "pos": {"plugins_mode": "pixel", # pixel
- "base": view_dict[view]["crop_img_base"], # nw,nc,ne,ec ... 各个方向参考点
- "value": view_dict[view]["crop_img_value"],
- },
- "color_fill": bg_color,
- })
- # 处理圆角
- data.append({"command": "radius", # radius
- "plugins_mode": "relative", # pixel 相对(短边),或绝对像素
- "circular_pos": (1, 1, 1, 1), # 从左上角顺时针,记录圆角数量
- "value": 100, # 固定值,如果为百分比,则为0
- "percentage": 0, }) # 百分比
- to_paste_img = self.deal_one_pic(to_paste_img, data)
- # 粘贴到白底图上
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": to_paste_img},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": view_dict[view]["paste_img_base"], # nw,nc,ne,ec ... 各个方向参考点
- "value": view_dict[view]["paste_img_value"],
- },
- "color_fill": bg_color,
- })
- bg_c = Image.new("RGB", (1200, 848), (255, 255, 255))
- bg_c_img = self.deal_one_pic(bg_c, data)
- to_paste_img = self.deal_one_pic(bg_c_img, data)
- detailed_images.append(to_paste_img)
- """ 制作角度展示图 """
- # 角度展示
- goods_art_no_list = list(self.data.keys())
- for index, goods_art_no in enumerate(goods_art_no_list):
- if index == 0:
- name_list = ["俯视", "侧视", "后跟", "鞋底"]
- else:
- name_list = ["俯视", ]
- for _name in name_list:
- # 处理图片,需要粘贴到背景等处理
- if _name not in self.data[goods_art_no]:
- continue
- _image = self.data[goods_art_no][_name]
- data = []
- data.append({"command": "resize",
- "plugins_mode": "pixel", # pixel 相对(宽度、高度、其他参考图),或绝对像素
- "base": "width",
- # base:pixel,width,height,by_im 基于长边、基于短边 (基于短边时,则缩放到指定尺寸)by_im确保能塞进参考图内
- "value": 500 if _name == "后跟" else 1058, # 固定值,如果为百分比,则为0
- }) # 百分比
- _image = self.deal_one_pic(img=_image, data=data)
- data = []
- data.append({
- "command": "paste_img",
- "img": {"im": _image},
- "pos": {"plugins_mode": "pixel", # pixel
- "base": "center", # nw,nc,ne,ec ... 各个方向参考点
- "value": (0, 0),
- "percentage": (0, 0),
- },
- "margins": (0, 0, 0, 0), # 上下左右边距
- })
- bg_img = Image.new("RGB", (1200, int(_image.height + 50)), bg_color)
- _image = self.deal_one_pic(img=bg_img, data=data)
- # _image.show()
- detailed_images.append(_image)
- detailed_images.append(Image.new("RGB", (1200, 50), (255, 255, 255)))
- detailed_images.append(Image.open(r"resources\detail_image_3\image (3).jpg"))
- """ 制作详细图 """
- output_path = "{out_put_dir}/{goods_no}/details".format(out_put_dir=self.out_put_dir, goods_no=self.goods_no)
- self.create_folder(output_path)
- for index, im in enumerate(detailed_images):
- im.save("{}/{}({}).png".format(output_path, self.goods_no, str(index + 11).zfill(2)))
- img = self.add_pic(detailed_images)
- img.save("{}/0_{}_拼接图.png".format(self.out_put_dir, self.goods_no))
- return True
- def create_folder(self, path):
- def check_folder(__path):
- if not os.path.exists(__path):
- os.makedirs(__path)
- return False
- return True
- # 文件夹不存在,创建货号子集文件夹
- if not check_folder(path):
- pass
- # for name in ["原始图", "原始图_已抠图", "800x800", "200images"]:
- # other_path = path + "/" + name
- # check_folder(other_path)
- def add_pic(self, detailed_images):
- if not detailed_images:
- return
- page_len = 0
- for index, im in enumerate(detailed_images):
- page_len += im.height
- bg_im = Image.new("RGB", (im.width, page_len), (255, 255, 255))
- n = 0
- for index, im in enumerate(detailed_images):
- bg_im.paste(im, (0, n))
- n += im.height
- # bg_im.show()
- return bg_im
- def get_goods_pos(self, im, cut_image):
- # 保留多余内容
- old_x, old_y = im.size
- x1, y1, x2, y2 = cut_image.getbbox()
- goods_w, goods_h = x2 - x1, y2 - y1
- _w, _h = int(goods_w / 10), int(goods_h / 10) # 上下左右扩展位置
- new_x1, new_y1, new_x2, new_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h # 防止超限
- new_x1 = 0 if new_x1 < 0 else new_x1
- new_y1 = 0 if new_y1 < 0 else new_y1
- new_x2 = old_x if new_x2 > old_x else new_x2
- new_y2 = old_y if new_y2 > old_y else new_y2
- # 剪切掉多余的内容,保留阴影
- im = im.crop((new_x1, new_y1, new_x2, new_y2)) # 切图
- return im
- def set_dict(self, one_dict):
- _ = defaultdict(str)
- for i, v in one_dict.items():
- if isinstance(v, dict):
- v = self.set_dict(v)
- _[i] = v
- return _
- def deal_one_pic(self, img: Image, data=None):
- """
- 通用图片处理器
- 1、基于某原始图,进行加工,包括粘贴、单图处理等逻辑
- """
- data = [self.set_dict(x) for x in data]
- for command in data:
- if command["command"] == "resize":
- img = OnePicDeal().resize(img, command)
- continue
- if command["command"] == "paste_img":
- img = OnePicDeal().paste_img(img, command)
- continue
- if command["command"] == "crop_img":
- img = OnePicDeal().crop_img(img, command)
- continue
- if command["command"] == "radius":
- img = OnePicDeal().radius(img, command)
- continue
- if command["command"] == "add_text":
- img = OnePicDeal().add_text(img, command)
- continue
- return img
- def get_overlay_pic(self, pil_img_1, pil_img_2, color):
- im_w, im_h = pil_img_1.size
- cv_im = cv2.cvtColor(np.asarray(pil_img_1), cv2.COLOR_RGB2BGR)
- # 创建一张纯色底图
- image_white = Image.new("RGB", (im_w, im_h), color)
- cv_image_white = cv2.cvtColor(np.asarray(image_white), cv2.COLOR_RGB2BGR)
- new_im = self.to_color_2(cv_image_white, cv_im)
- # new_im = cv2.addWeighted(new_im, 0.7, cv_im_2, 0.3, 0)
- # new_im = cv2.add(new_im, cv_im_2)
- new_im = Image.fromarray(cv2.cvtColor(new_im, cv2.COLOR_BGR2RGB))
- new_im.paste(pil_img_2, (0, 0), pil_img_2)
- return new_im
- def to_color_2(self, target, blend): # 正片叠底
- return np.array(np.multiply(target / 256, blend / 256) * 256, dtype=np.uint8)
- def to_color_1(self, img1, img2): # PS颜色模式
- img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
- img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
- img2[:, :, 0] = img1[:, :, 0]
- img2[:, :, 1] = img1[:, :, 1]
- res = cv2.cvtColor(img2, cv2.COLOR_HSV2BGR)
- return res
- if __name__ == '__main__':
- _path = r"D:\MyDocuments\PythonCode\MyPython\red_dragonfly\deal_pics\auto_capture\IPC\output\2023-11-06"
- goods_no_dict = {}
- for goods_art_no in os.listdir(_path):
- if not os.path.isdir("{}/{}".format(_path, goods_art_no)):
- continue
- if len(goods_art_no) < 10:
- print("{}--长度异常".format(goods_art_no))
- continue
- # print(goods_art_no)
- goods_no = goods_art_no[:9]
- if goods_no not in goods_no_dict:
- goods_no_dict[goods_no] = {}
- goods_no_dict[goods_no][goods_art_no] = {}
- # 获取该货号下所有素材图 阴影图处理
- source_material_path = "{}/{}/阴影图处理".format(_path, goods_art_no)
- if not os.path.exists(source_material_path):
- print("{}--缺少 阴影图处理 文件夹".format(goods_art_no))
- continue
- _ = {}
- if len(os.listdir(source_material_path)) % 2 != 0:
- print("{}--阴影图处理 文件错误".format(goods_art_no))
- continue
- name_list = ["俯视", "侧视", "后跟", "鞋底", "内里"]
- for pic in os.listdir(source_material_path):
- # print(pic)
- _pic = pic.replace(".png", "")
- _pic = _pic.split("_")
- if len(_pic) != 3:
- continue
- _["{}-{}".format(_pic[1], _pic[2])] = "{}/{}".format(source_material_path, pic)
- goods_no_dict[goods_no][goods_art_no] = _
- # print(_)
- # 准备拼接处理
- for goods_no, goods_no_value in goods_no_dict.items():
- # if goods_no == "AC5200054":
- print("开始处理-----{}".format(goods_no))
- GenerateDetailPic(goods_no, goods_no_value)
- # raise 1
- # print(goods_no_dict)
|