import os import sys from config import SUPPORTED_INPUT_EXTENSIONS, SUPPORTED_OUTPUT_EXTENSIONS, WORK_DIR from watermark import watermark_image_tiled, increment_count, _parse_output_spec def print_banner(): """启动时显示完整帮助菜单。""" print("=" * 50) print(" imgwatermark - 图像水印工具 v1.0") print(" 支持: .jpg .png .bmp .gif .tiff .webp") print(" 输出: jpg / png / bmp / gif / tiff / webp") print("=" * 50) print("命令:") print(" <图片路径> \"水印内容\" 加水印,输出到原目录") print(" <图片路径>>.png \"内容\" 加水印并转换格式") print(" <图片路径>>./output.png 输出到指定目录") print(" <图片路径>>../output.png 输出到上级目录") print(" /exit 或 exit 退出程序") print(" /get 或 get 显示已处理图片统计") print() def print_stats(): count = 0 if os.path.exists(os.path.join(WORK_DIR, ".processed_count")): with open(os.path.join(WORK_DIR, ".processed_count"), "r", encoding="utf-8") as f: try: count = int(f.read().strip()) except ValueError: pass print(f"已处理图片总数: {count} 张") def process_single(image_arg, text): """处理单张图片:可选格式转换/输出路径,添加平铺水印,计数+1。""" # 去掉首尾引号(兼容命令行传入带引号的路径) image_arg = image_arg.strip().strip('"').strip("'") text = text.strip().strip('"').strip("'") output_spec = None if ">" in image_arg: parts = image_arg.rsplit(">", 1) image_arg = parts[0].strip().strip('"').strip("'") # 分割后去除左端引号 output_spec = parts[1].strip() else: image_arg = image_arg.strip().strip('"').strip("'") # 验证输入路径 input_path = image_arg if not os.path.isfile(input_path): print(f"❌ 找不到输入图片: {input_path}") return _, ext = os.path.splitext(input_path) if ext.lower() not in SUPPORTED_INPUT_EXTENSIONS: print(f"❌ 不支持的输入格式: {ext},支持的格式: {', '.join(sorted(SUPPORTED_INPUT_EXTENSIONS))}") return # 处理输出规格 output_path = None output_ext = None if output_spec: try: output_path, output_ext = _parse_output_spec(output_spec, input_path) except ValueError as e: print(f"❌ {e}") return else: # 无输出规格,保持原格式,输出到原目录 _, output_ext = os.path.splitext(input_path) input_dir = os.path.dirname(os.path.abspath(input_path)) base_name = os.path.basename(input_path) name_no_ext = os.path.splitext(base_name)[0] output_path = os.path.join(input_dir, f"{name_no_ext}_watermarked{output_ext.lower()}") # 添加平铺水印 try: final_path = watermark_image_tiled(input_path, text, output_path=output_path, output_ext=output_ext) total = increment_count() print(f"✅ 已保存: {final_path}") print(f"📊 累计处理图片: {total} 张") except Exception as e: print(f"❌ 处理失败: {e}") def main(): if len(sys.argv) >= 3: # 非交互模式:直接处理一张图片 process_single(sys.argv[1], sys.argv[2]) return print_banner() while True: try: cmd = input("\n> ").strip() except (EOFError, KeyboardInterrupt): print("\n再见!") break if not cmd: continue # 处理命令前缀(支持带/或不带/) if cmd in ("/exit", "exit"): print("再见!") break elif cmd in ("/get", "get"): print_stats() elif cmd in ("/help", "help"): print_banner() elif ">" in cmd: # 格式转换模式: "图片路径>.png 水印内容" 或 "图片路径>./output.png 水印内容" parts = cmd.split(">", 1) image_part = parts[0].strip() rest = parts[1].strip() if not rest: print("❌ 缺少输出规格或水印内容,请重试。") continue # 分析 rest 部分:可能是 "格式 文本" 或 "路径 文本" tokens = rest.split(None, 1) if len(tokens) == 2: output_spec, text = tokens full_arg = f"{image_part}>{output_spec}" elif len(tokens) == 1: # 只有一个 token,判断是否是路径(包含 . 或 / 或 \) candidate = tokens[0] if "." in candidate or "/" in candidate or "\\" in candidate: # 可能是路径,但缺少水印内容 print("❌ 缺少水印内容,请重试。") continue else: # 是格式名 output_spec = candidate # 继续读取后续内容作为水印文本(如果有) print("❌ 缺少水印内容,请重试。") continue else: print("❌ 格式错误,请重试。") continue process_single(full_arg, text) else: # 普通模式: "图片路径 水印内容" parts = cmd.split(None, 1) if len(parts) < 2: print("❌ 格式错误,需要提供图片路径和水印内容。") continue image_arg, text = parts process_single(image_arg, text) if __name__ == "__main__": main()