From f1b96100d4333df9777bfedd3f04961b552c217d Mon Sep 17 00:00:00 2001 From: ypshidifu Date: Fri, 18 Sep 2026 20:49:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=AF=E5=BE=84=E5=BC=95?= =?UTF-8?q?=E5=8F=B7=E5=A4=84=E7=90=86=EF=BC=8C=E5=AE=8C=E5=96=84=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E8=8F=9C=E5=8D=95=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .processed_count | 1 + main.py | 68 ++++++++++++++++++++++++++++-------------------- watermark.py | 29 ++++++++++++++------- 3 files changed, 61 insertions(+), 37 deletions(-) create mode 100644 .processed_count diff --git a/.processed_count b/.processed_count new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/.processed_count @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/main.py b/main.py index 30a1bcb..f6b2b22 100644 --- a/main.py +++ b/main.py @@ -1,20 +1,28 @@ import os import sys -from watermark import watermark_image, increment_count, load_font -from config import OUTPUT_DIR, SUPPORTED_INPUT_EXTENSIONS, WORK_DIR +from watermark import watermark_image, increment_count +from config import OUTPUT_DIR, SUPPORTED_INPUT_EXTENSIONS, SUPPORTED_OUTPUT_EXTENSIONS, WORK_DIR def print_help(): help_text = """ -用法: - "图片路径" "水印内容" 加水印,保持原格式输出 - "图片路径>输出格式" "水印内容" 加水印并转换格式(格式可选:jpg/png/bmp/gif/tiff/webp) - /exit 退出程序 - /get 查询已处理图片总数 +======================================== + imgwatermark - 图像水印工具 v1.0 + 支持: .jpg .png .bmp .gif .tiff .webp + 输出: jpg / png / bmp / gif / tiff / webp +======================================== -示例: - photo.jpg "版权所有" - photo.jpg>PNG "2026" +命令: + <图片路径> \"水印内容\" 加水印,保持原格式输出 + <图片路径>>.png \"内容\" 加水印并转换格式(格式可选:jpg/png/bmp/gif/tiff/webp) + /exit 或 exit 退出程序 + /get 或 get 显示已处理图片统计 + /help 或 help 显示本帮助信息 + +示例: + D:\\img\\photo.jpg \"版权所有\" + D:\\img\\photo.jpg>.png \"2026\" + /get """ print(help_text.strip()) @@ -27,23 +35,26 @@ def print_stats(): count = int(f.read().strip()) except ValueError: pass - print(f"当前已处理图片数量: {count}") + print(f"已处理图片总数: {count} 张") def process_single(image_arg, text): + """处理单张图片:可选格式转换,添加水印,计数+1。""" + # 去掉首尾引号(兼容命令行传入带引号的路径) + image_arg = image_arg.strip().strip('"').strip("'") + text = text.strip().strip('"').strip("'") + if ">" not in image_arg: - # 无格式转换,保持原格式 output_ext = None else: parts = image_arg.rsplit(">", 1) - image_arg, out_ext = parts - out_ext = out_ext.strip().lstrip(".") + image_arg, out_ext = parts[0].strip(), parts[1].strip().lstrip(".") if out_ext.lower() not in SUPPORTED_INPUT_EXTENSIONS: - print(f"不支持的输出格式: .{out_ext},支持的格式: {', '.join(sorted(SUPPORTED_INPUT_EXTENSIONS))}") + print(f"不支持的输出格式: .{out_ext},支持的格式: {', '.join(sorted(SUPPORTED_OUTPUT_EXTENSIONS))}") return output_ext = f".{out_ext.lower()}" - input_path = image_arg.strip() + input_path = image_arg if not os.path.isfile(input_path): print(f"找不到输入图片: {input_path}") return @@ -65,10 +76,10 @@ def main(): process_single(sys.argv[1], sys.argv[2]) return - print("========================================") - print(" 图像水印工具 v1.0") + print("=" * 40) + print(" imgwatermark - 图像水印工具 v1.0") print(" 输入 /help 查看帮助") - print("========================================") + print("=" * 40) while True: try: cmd = input("\n> ").strip() @@ -79,28 +90,29 @@ def main(): if not cmd: continue - if cmd == "/exit" or cmd == "exit": + # 处理命令前缀(支持带/或不带/) + if cmd in ("/exit", "exit"): print("再见!") break - elif cmd == "/get": + elif cmd in ("/get", "get"): print_stats() - elif cmd == "/help": + elif cmd in ("/help", "help"): print_help() elif ">" in cmd: - # 格式转换模式: "图片>格式 水印内容" + # 格式转换模式: "图片路径>.png 水印内容" 或 "图片路径>PNG 水印内容" parts = cmd.split(">", 1) image_part = parts[0].strip() rest = parts[1].strip() if not rest: print("缺少水印内容,请重试。输入 /help 查看帮助。") continue - # 找出 ">格式 " 后面的水印文本(用 ">格式 " 分割后取第二部分) - if " " in rest: - final_format, text = rest.split(" ", 1) - full_arg = f"{image_part}>{final_format}" - else: + # rest 中第一个空格前是格式,后面是水印文本 + tokens = rest.split(None, 1) + if len(tokens) < 2: print("格式参数后缺少水印内容,请重试。输入 /help 查看帮助。") continue + final_format, text = tokens + full_arg = f"{image_part}>{final_format}" process_single(full_arg, text) else: # 普通模式: "图片路径 水印内容" diff --git a/watermark.py b/watermark.py index 80bd441..5812b27 100644 --- a/watermark.py +++ b/watermark.py @@ -1,9 +1,9 @@ import os from PIL import Image, ImageDraw, ImageFont -from config import OUTPUT_DIR, SUPPORTED_INPUT_EXTENSIONS, SUPPORTED_OUTPUT_EXTENSIONS +from config import OUTPUT_DIR, SUPPORTED_INPUT_EXTENSIONS, SUPPORTED_OUTPUT_EXTENSIONS, STATS_FILE -def load_font(size=40): +def load_font(size=48): """根据系统加载合适的字体文件。""" candidates = [ r"C:\Windows\Fonts\msyh.ttc", @@ -17,6 +17,14 @@ def load_font(size=40): return ImageFont.load_default() +def _strip_quotes(s): + """去掉首尾的引号(\"、')""" + s = s.strip() + if len(s) >= 2 and s[0] == s[-1] and s[0] in ('"', "'"): + return s[1:-1] + return s + + def watermark_image(input_path, text, output_path=None, output_ext=None): """ 给图片添加水印并保存。 @@ -31,7 +39,7 @@ def watermark_image(input_path, text, output_path=None, output_ext=None): """ img = Image.open(input_path).convert("RGBA") - # 水印图层 + # 水印图层(右下角) overlay = Image.new("RGBA", img.size, (0, 0, 0, 0)) draw = ImageDraw.Draw(overlay) @@ -42,28 +50,31 @@ def watermark_image(input_path, text, output_path=None, output_ext=None): x = img.width - tw - 20 y = img.height - th - 20 - # 半透明背景 + # 半透明圆角背景 draw.rounded_rectangle( [x - 8, y - 4, x + tw + 8, y + th + 4], radius=6, fill=(0, 0, 0, 140), ) - # 文字 + # 白色文字 draw.text((x, y), text, fill=(255, 255, 255, 255), font=font) - # 合成 + # 合成并转 RGB result = Image.alpha_composite(img, overlay) result = result.convert("RGB") - # 确定输出路径与格式 + # 确定输出格式 if output_ext is None: _, ext = os.path.splitext(input_path) output_ext = ext.lower() else: output_ext = output_ext.lower() if output_ext not in SUPPORTED_OUTPUT_EXTENSIONS: - raise ValueError(f"不支持的输出格式: {output_ext},支持的格式: {SUPPORTED_OUTPUT_EXTENSIONS}") + raise ValueError( + f"不支持的输出格式: {output_ext},支持的格式: {', '.join(sorted(SUPPORTED_OUTPUT_EXTENSIONS))}" + ) + # 确定输出路径 if output_path is None: base_name = os.path.basename(input_path) name_no_ext = os.path.splitext(base_name)[0] @@ -85,7 +96,7 @@ def watermark_image(input_path, text, output_path=None, output_ext=None): def increment_count(): - """已处理图片计数 +1。""" + """已处理图片计数 +1,返回新总数。""" count = 0 if os.path.exists(STATS_FILE): with open(STATS_FILE, "r", encoding="utf-8") as f: