|
@@ -90,7 +90,7 @@ def _detect_band_widths(canvas, band_color=None, tolerance=30):
|
|
|
band_color 为 None 时,从模板左上角采样取中值作为基准色。
|
|
band_color 为 None 时,从模板左上角采样取中值作为基准色。
|
|
|
"""
|
|
"""
|
|
|
a = np.asarray(canvas)
|
|
a = np.asarray(canvas)
|
|
|
- rgb = a[:, :, :3].astype(float) # 只用 RGB 通道做颜色判定
|
|
|
|
|
|
|
+ rgb = a[:, :, :3].astype(float) # 只用 RGB 通道做颜色判定
|
|
|
alpha = a[:, :, 3] if a.shape[2] >= 4 else None # 有透明通道时排除透明像素
|
|
alpha = a[:, :, 3] if a.shape[2] >= 4 else None # 有透明通道时排除透明像素
|
|
|
H, W = rgb.shape[:2]
|
|
H, W = rgb.shape[:2]
|
|
|
if band_color is None:
|
|
if band_color is None:
|
|
@@ -240,11 +240,14 @@ def compose_shoe_main_image(
|
|
|
cell_pad=4, # 每格上下留白
|
|
cell_pad=4, # 每格上下留白
|
|
|
shoe_width_limit_ratio=1.15, # 鞋子最大宽度 = 该格浅色区域宽度 * 比例(可略溢出)
|
|
shoe_width_limit_ratio=1.15, # 鞋子最大宽度 = 该格浅色区域宽度 * 比例(可略溢出)
|
|
|
shoe_scale=1.0, # 鞋子最终尺寸缩放系数:1.0=自动适配大小,>1 放大,<1 缩小
|
|
shoe_scale=1.0, # 鞋子最终尺寸缩放系数:1.0=自动适配大小,>1 放大,<1 缩小
|
|
|
- label_pos="bottom", # 颜色文本位置:"bottom"下方 | "right"右侧(图1样式)
|
|
|
|
|
|
|
+ # 颜色文本位置:下方组 bottom(居中)/bottom-left(左对齐)/bottom-right(右对齐);
|
|
|
|
|
+ # 右侧组 right(居中)/right-top(顶对齐)/right-bottom(底对齐)
|
|
|
|
|
+ label_pos="bottom",
|
|
|
label_font_size=15,
|
|
label_font_size=15,
|
|
|
label_color=(60, 60, 60),
|
|
label_color=(60, 60, 60),
|
|
|
label_dot=True, # 颜色文本前是否画小圆点(取鞋子主色)
|
|
label_dot=True, # 颜色文本前是否画小圆点(取鞋子主色)
|
|
|
label_gap=5, # 鞋与颜色文本的间距
|
|
label_gap=5, # 鞋与颜色文本的间距
|
|
|
|
|
+ label_offset=(0, 0), # 颜色文本偏移量 (dx, dy):dx 左右(>0 右移),dy 上下(>0 下移)
|
|
|
shoe_center_offset=0, # 鞋子中心相对浅色区域中心的水平偏移
|
|
shoe_center_offset=0, # 鞋子中心相对浅色区域中心的水平偏移
|
|
|
# ---- C区域:底部文本信息 ----
|
|
# ---- C区域:底部文本信息 ----
|
|
|
info_bar=True, # True=画圆角信息条;False=只画文字
|
|
info_bar=True, # True=画圆角信息条;False=只画文字
|
|
@@ -415,6 +418,13 @@ def compose_shoe_main_image(
|
|
|
.format(area_top, area_bottom))
|
|
.format(area_top, area_bottom))
|
|
|
cell_h = (area_bottom - area_top) / n
|
|
cell_h = (area_bottom - area_top) / n
|
|
|
lab_font = _load_font(font_path, label_font_size)
|
|
lab_font = _load_font(font_path, label_font_size)
|
|
|
|
|
+ # 颜色文本偏移量 (dx, dy):dx 左右(>0 右移),dy 上下(>0 下移)
|
|
|
|
|
+ try:
|
|
|
|
|
+ label_dx, label_dy = int(label_offset[0]), int(label_offset[1])
|
|
|
|
|
+ except (TypeError, ValueError, IndexError):
|
|
|
|
|
+ label_dx, label_dy = 0, 0
|
|
|
|
|
+ # 文本位置分组:below 组在鞋下方(bottom/bottom-left/bottom-right),其余在鞋右侧
|
|
|
|
|
+ below = label_pos in ("bottom", "bottom-left", "bottom-right")
|
|
|
|
|
|
|
|
for i, item in enumerate(shoes):
|
|
for i, item in enumerate(shoes):
|
|
|
if isinstance(item, str):
|
|
if isinstance(item, str):
|
|
@@ -422,6 +432,7 @@ def compose_shoe_main_image(
|
|
|
else:
|
|
else:
|
|
|
shoe_src = item.get("image")
|
|
shoe_src = item.get("image")
|
|
|
color_name = str(item.get("color", ""))
|
|
color_name = str(item.get("color", ""))
|
|
|
|
|
+ # print("shoe_src", shoe_src)
|
|
|
shoe_im = _trim_alpha(_to_image(shoe_src).convert("RGBA"))
|
|
shoe_im = _trim_alpha(_to_image(shoe_src).convert("RGBA"))
|
|
|
sw0, sh0 = shoe_im.size
|
|
sw0, sh0 = shoe_im.size
|
|
|
|
|
|
|
@@ -442,7 +453,7 @@ def compose_shoe_main_image(
|
|
|
|
|
|
|
|
# 该格内鞋子可占用的最大盒子:已扣除留白与颜色文本,
|
|
# 该格内鞋子可占用的最大盒子:已扣除留白与颜色文本,
|
|
|
# 保证"鞋 + 颜色名称"整体都落在浅色区内、绝不超出。
|
|
# 保证"鞋 + 颜色名称"整体都落在浅色区内、绝不超出。
|
|
|
- if label_pos == "bottom":
|
|
|
|
|
|
|
+ if below:
|
|
|
box_w = bw - 2 * margin
|
|
box_w = bw - 2 * margin
|
|
|
box_h = cell_h - 2 * int(cell_pad) - (label_h + int(label_gap) if color_name else 0)
|
|
box_h = cell_h - 2 * int(cell_pad) - (label_h + int(label_gap) if color_name else 0)
|
|
|
else: # right:鞋在左、文本紧跟其右,两者都要在带内
|
|
else: # right:鞋在左、文本紧跟其右,两者都要在带内
|
|
@@ -457,7 +468,7 @@ def compose_shoe_main_image(
|
|
|
if (sw, sh) != (sw0, sh0):
|
|
if (sw, sh) != (sw0, sh0):
|
|
|
shoe_im = shoe_im.resize((sw, sh), Image.LANCZOS)
|
|
shoe_im = shoe_im.resize((sw, sh), Image.LANCZOS)
|
|
|
|
|
|
|
|
- if label_pos == "bottom":
|
|
|
|
|
|
|
+ if below:
|
|
|
sx = int(max(margin, (bw - sw) / 2 + float(shoe_center_offset)))
|
|
sx = int(max(margin, (bw - sw) / 2 + float(shoe_center_offset)))
|
|
|
block_h = sh + (int(label_gap) + label_h if color_name else 0)
|
|
block_h = sh + (int(label_gap) + label_h if color_name else 0)
|
|
|
sy = int(cell_y0 + max(0, (cell_h - block_h) / 2))
|
|
sy = int(cell_y0 + max(0, (cell_h - block_h) / 2))
|
|
@@ -472,13 +483,27 @@ def compose_shoe_main_image(
|
|
|
|
|
|
|
|
if color_name:
|
|
if color_name:
|
|
|
dot_color = _dominant_color(shoe_im) if label_dot else None
|
|
dot_color = _dominant_color(shoe_im) if label_dot else None
|
|
|
- if label_pos == "bottom":
|
|
|
|
|
- ly = sy + sh + int(label_gap)
|
|
|
|
|
- _draw_color_label(draw, lab_font, color_name, int(sx + sw / 2), ly,
|
|
|
|
|
- label_color, dot=dot_color, align="center")
|
|
|
|
|
|
|
+ if below:
|
|
|
|
|
+ # 鞋下方:垂直在鞋底+间距;水平按 bottom / bottom-left / bottom-right 对齐
|
|
|
|
|
+ ly = sy + sh + int(label_gap) + label_dy
|
|
|
|
|
+ if label_pos == "bottom-right": # 右对齐:文本右缘贴鞋右缘
|
|
|
|
|
+ lx, align = int(sx + sw - label_w) + label_dx, "left"
|
|
|
|
|
+ elif label_pos == "bottom-left": # 左对齐:文本左缘贴鞋左缘
|
|
|
|
|
+ lx, align = int(sx) + label_dx, "left"
|
|
|
|
|
+ else: # bottom:水平居中
|
|
|
|
|
+ lx, align = int(sx + sw / 2) + label_dx, "center"
|
|
|
|
|
+ _draw_color_label(draw, lab_font, color_name, lx, ly,
|
|
|
|
|
+ label_color, dot=dot_color, align=align)
|
|
|
else:
|
|
else:
|
|
|
- ly = sy + (sh - label_h) // 2
|
|
|
|
|
- _draw_color_label(draw, lab_font, color_name, label_x, ly,
|
|
|
|
|
|
|
+ # 鞋右侧:水平在鞋右+间距;垂直按 right / right-top / right-bottom 对齐
|
|
|
|
|
+ lx = int(label_x) + label_dx
|
|
|
|
|
+ if label_pos == "right-top": # 顶对齐:文本顶贴鞋顶
|
|
|
|
|
+ ly = sy + label_dy
|
|
|
|
|
+ elif label_pos == "right-bottom": # 底对齐:文本底贴鞋底
|
|
|
|
|
+ ly = sy + sh - label_h + label_dy
|
|
|
|
|
+ else: # right:垂直居中
|
|
|
|
|
+ ly = sy + (sh - label_h) // 2 + label_dy
|
|
|
|
|
+ _draw_color_label(draw, lab_font, color_name, lx, ly,
|
|
|
label_color, dot=dot_color, align="left")
|
|
label_color, dot=dot_color, align="left")
|
|
|
|
|
|
|
|
# ---------- 调试叠加图 ----------
|
|
# ---------- 调试叠加图 ----------
|