|
|
@@ -0,0 +1,1177 @@
|
|
|
+"""
|
|
|
+步骤:
|
|
|
+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)
|