154 lines
5.5 KiB
Python
154 lines
5.5 KiB
Python
import os
|
||
import sys
|
||
from watermark import watermark_image_tiled, increment_count, _parse_output_spec
|
||
from config import SUPPORTED_INPUT_EXTENSIONS, SUPPORTED_OUTPUT_EXTENSIONS, WORK_DIR
|
||
|
||
|
||
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()
|
||
output_spec = parts[1].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()
|