147 lines
5.7 KiB
Python
147 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Writech 商标图像处理脚本
|
|
- 去除蓝色底色,生成透明 PNG
|
|
- 系列化简洁处理,适配商标注册
|
|
"""
|
|
from PIL import Image, ImageFilter, ImageDraw
|
|
import os
|
|
|
|
SRC = "/Users/jiahong/Library/Application Support/Qoder/SharedClientCache/cache/images/7702e5b9/截屏2026-03-04 10.30.55-0be34715.jpg"
|
|
OUT_DIR = "/Users/jiahong/Documents/Job/docs/jiahong_docs/education/writech_logo"
|
|
os.makedirs(OUT_DIR, exist_ok=True)
|
|
|
|
img = Image.open(SRC).convert("RGBA")
|
|
w, h = img.size
|
|
pixels = img.load()
|
|
|
|
# ========== 1. 去蓝色底色 → 透明 PNG ==========
|
|
def remove_blue_bg(image, tolerance=100):
|
|
"""将蓝色背景区域变为透明"""
|
|
result = image.copy()
|
|
px = result.load()
|
|
for y in range(result.height):
|
|
for x in range(result.width):
|
|
r, g, b, a = px[x, y]
|
|
# 蓝色背景特征: B高, R低, G中低
|
|
# 原图蓝色约 (70, 130, 210) 左右
|
|
if b > 140 and r < 130 and b > r + 40:
|
|
# 越接近纯蓝越透明
|
|
blue_ratio = (b - r) / max(b, 1)
|
|
if blue_ratio > 0.3:
|
|
px[x, y] = (r, g, b, 0)
|
|
# 处理边缘过渡区 (半透明)
|
|
elif b > 120 and r < 150 and b > r + 20:
|
|
alpha = int(255 * (1 - (b - r) / max(b, 1)))
|
|
alpha = max(0, min(255, alpha))
|
|
px[x, y] = (r, g, b, alpha)
|
|
return result
|
|
|
|
print("生成 1: 透明底色原图...")
|
|
transparent = remove_blue_bg(img)
|
|
transparent.save(os.path.join(OUT_DIR, "writech_logo_transparent.png"), "PNG")
|
|
|
|
# ========== 2. 纯绿色线条版 (最简洁, 商标注册首选) ==========
|
|
print("生成 2: 纯绿色线条版...")
|
|
def extract_green_lines(image):
|
|
"""提取绿色线条,黑色描边,白色/透明背景"""
|
|
result = Image.new("RGBA", image.size, (0, 0, 0, 0))
|
|
px_src = image.load()
|
|
px_dst = result.load()
|
|
for y in range(image.height):
|
|
for x in range(image.width):
|
|
r, g, b, a = px_src[x, y]
|
|
# 绿色线条: G高, R中高, B低
|
|
# 原图绿色约 (160, 210, 50) 左右
|
|
if g > 140 and g > b + 50 and g > r * 0.8:
|
|
# 保留为纯绿色
|
|
intensity = g / 255.0
|
|
px_dst[x, y] = (100, 190, 60, int(255 * intensity))
|
|
return result
|
|
|
|
green_lines = extract_green_lines(img)
|
|
green_lines.save(os.path.join(OUT_DIR, "writech_logo_green_lines.png"), "PNG")
|
|
|
|
# ========== 3. 纯黑色线条版 (单色商标注册) ==========
|
|
print("生成 3: 纯黑色线条版...")
|
|
def extract_black_lines(image):
|
|
"""提取线条并转为纯黑色,适合单色商标"""
|
|
result = Image.new("RGBA", image.size, (0, 0, 0, 0))
|
|
px_src = image.load()
|
|
px_dst = result.load()
|
|
for y in range(image.height):
|
|
for x in range(image.width):
|
|
r, g, b, a = px_src[x, y]
|
|
if g > 140 and g > b + 50 and g > r * 0.8:
|
|
intensity = g / 255.0
|
|
px_dst[x, y] = (0, 0, 0, int(255 * intensity))
|
|
return result
|
|
|
|
black_lines = extract_black_lines(img)
|
|
black_lines.save(os.path.join(OUT_DIR, "writech_logo_black.png"), "PNG")
|
|
|
|
# ========== 4. 白底黑线版 (传统商标注册用) ==========
|
|
print("生成 4: 白底黑线版...")
|
|
white_bg = Image.new("RGBA", img.size, (255, 255, 255, 255))
|
|
white_bg = Image.alpha_composite(white_bg, black_lines)
|
|
white_bg.save(os.path.join(OUT_DIR, "writech_logo_white_bg_black.png"), "PNG")
|
|
|
|
# ========== 5. 白底绿线版 ==========
|
|
print("生成 5: 白底绿线版...")
|
|
white_bg2 = Image.new("RGBA", img.size, (255, 255, 255, 255))
|
|
white_bg2 = Image.alpha_composite(white_bg2, green_lines)
|
|
white_bg2.save(os.path.join(OUT_DIR, "writech_logo_white_bg_green.png"), "PNG")
|
|
|
|
# ========== 6. 正方形裁切版 (适配商标规范尺寸) ==========
|
|
print("生成 6: 正方形版本...")
|
|
size = max(w, h)
|
|
square = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
|
offset_x = (size - w) // 2
|
|
offset_y = (size - h) // 2
|
|
square.paste(transparent, (offset_x, offset_y), transparent)
|
|
# 缩放到标准尺寸 1000x1000
|
|
square_1000 = square.resize((1000, 1000), Image.LANCZOS)
|
|
square_1000.save(os.path.join(OUT_DIR, "writech_logo_square_1000.png"), "PNG")
|
|
|
|
# ========== 7. 小尺寸 icon 版 (256x256, 128x128, 64x64) ==========
|
|
print("生成 7: 多尺寸 icon...")
|
|
for sz in [512, 256, 128, 64]:
|
|
icon = square.resize((sz, sz), Image.LANCZOS)
|
|
icon.save(os.path.join(OUT_DIR, f"writech_icon_{sz}.png"), "PNG")
|
|
|
|
# ========== 8. 商标注册专用 - 极简轮廓版 ==========
|
|
print("生成 8: 极简轮廓版...")
|
|
# 先提取绿色通道做灰度,然后二值化得到清晰轮廓
|
|
gray = img.convert("L")
|
|
# 使用绿色通道强度作为阈值参考
|
|
r_ch, g_ch, b_ch, a_ch = img.split()
|
|
# 绿色减蓝色 = 线条区域
|
|
from PIL import ImageChops
|
|
diff = ImageChops.subtract(g_ch, b_ch)
|
|
# 二值化
|
|
threshold = 60
|
|
binary = diff.point(lambda p: 255 if p > threshold else 0, mode='1')
|
|
# 转回 RGBA 透明底
|
|
outline = Image.new("RGBA", img.size, (0, 0, 0, 0))
|
|
px_bin = binary.load()
|
|
px_out = outline.load()
|
|
for y in range(img.height):
|
|
for x in range(img.width):
|
|
if px_bin[x, y]:
|
|
px_out[x, y] = (0, 0, 0, 255)
|
|
outline.save(os.path.join(OUT_DIR, "writech_logo_outline.png"), "PNG")
|
|
|
|
# 白底轮廓版
|
|
white_outline = Image.new("RGBA", img.size, (255, 255, 255, 255))
|
|
white_outline = Image.alpha_composite(white_outline, outline)
|
|
white_outline.save(os.path.join(OUT_DIR, "writech_logo_outline_white.png"), "PNG")
|
|
|
|
print(f"\n✅ 全部完成!输出目录: {OUT_DIR}")
|
|
print("生成文件列表:")
|
|
for f in sorted(os.listdir(OUT_DIR)):
|
|
if f.endswith('.png'):
|
|
fpath = os.path.join(OUT_DIR, f)
|
|
fsize = os.path.getsize(fpath)
|
|
im = Image.open(fpath)
|
|
print(f" {f:45s} {im.size[0]:5d}x{im.size[1]:<5d} {fsize//1024:>5d} KB")
|