from PIL import Image
import os
import argparse
def crop_bottom_pixels(input_path, output_path, pixels_to_remove):
"""
从图片底部截去指定像素高度
Args:
input_path (str): 输入图片路径
output_path (str): 输出图片路径
pixels_to_remove (int): 要从底部移除的像素数
"""
try:
# 打开图片
with Image.open(input_path) as img:
# 获取原始尺寸
width, height = img.size
# 检查要移除的像素是否合理
if pixels_to_remove >= height:
raise ValueError(f"要移除的像素数({pixels_to_remove})大于等于图片高度({height})")
if pixels_to_remove <= 0:
raise ValueError("要移除的像素数必须大于0")
# 计算裁剪区域 (left, top, right, bottom)
# 保持左边和右边不变,顶部不变,底部减去指定像素
crop_area = (0, 0, width, height - pixels_to_remove)
# 裁剪图片
cropped_img = img.crop(crop_area)
# 保存处理后的图片
cropped_img.save(output_path)
print(f"成功处理图片: {input_path}")
print(f"原尺寸: {width}x{height}, 新尺寸: {cropped_img.size}")
print(f"已从底部移除 {pixels_to_remove} 像素")
except FileNotFoundError:
print(f"错误: 找不到文件 {input_path}")
except Exception as e:
print(f"处理图片时出错: {e}")
def batch_crop_bottom_pixels(input_dir, output_dir, pixels_to_remove):
"""
批量处理目录中的图片
Args:
input_dir (str): 输入图片目录
output_dir (str): 输出图片目录
pixels_to_remove (int): 要从底部移除的像素数
"""
# 支持的图片格式
supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp')
# 创建输出目录
os.makedirs(output_dir, exist_ok=True)
# 遍历输入目录中的所有文件
processed_count = 0
for filename in os.listdir(input_dir):
if filename.lower().endswith(supported_formats):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
try:
crop_bottom_pixels(input_path, output_path, pixels_to_remove)
processed_count += 1
except Exception as e:
print(f"处理 {filename} 时出错: {e}")
print(f"\n批量处理完成,共处理 {processed_count} 个文件")
def interactive_mode():
"""交互式模式"""
print("=" * 50)
print("图片底部裁剪工具")
print("=" * 50)
while True:
print("\n请选择操作模式:")
print("1. 处理单个图片文件")
print("2. 批量处理图片目录")
print("3. 退出")
choice = input("\n请输入选项 (1/2/3): ").strip()
if choice == "1":
single_file_mode()
elif choice == "2":
batch_mode()
elif choice == "3":
print("感谢使用!")
break
else:
print("无效选项,请重新输入!")
def single_file_mode():
"""单文件处理模式"""
print("\n--- 单文件处理模式 ---")
# 获取输入文件路径
while True:
input_path = input("请输入要处理的图片文件路径: ").strip().strip('"')
if os.path.exists(input_path):
if os.path.isfile(input_path):
break
else:
print("输入的路径是一个目录,请输入文件路径!")
else:
print("文件不存在,请重新输入!")
# 获取要移除的像素数
while True:
try:
pixels_to_remove = int(input("请输入要从底部移除的像素数: "))
if pixels_to_remove > 0:
break
else:
print("像素数必须大于0,请重新输入!")
except ValueError:
print("请输入有效的数字!")
# 获取输出文件路径
default_output = f"{input_path}_cropped{os.path.splitext(input_path)[1]}"
output_path = input(f"请输入输出文件路径 (默认: {default_output}): ").strip().strip('"')
if not output_path:
output_path = default_output
# 处理图片
print("\n正在处理...")
crop_bottom_pixels(input_path, output_path, pixels_to_remove)
print("处理完成!")
def batch_mode():
"""批量处理模式"""
print("\n--- 批量处理模式 ---")
# 获取输入目录路径
while True:
input_dir = input("请输入包含图片的目录路径: ").strip().strip('"')
if os.path.exists(input_dir):
if os.path.isdir(input_dir):
break
else:
print("输入的路径是一个文件,请输入目录路径!")
else:
print("目录不存在,请重新输入!")
# 获取要移除的像素数
while True:
try:
pixels_to_remove = int(input("请输入要从底部移除的像素数: "))
if pixels_to_remove > 0:
break
else:
print("像素数必须大于0,请重新输入!")
except ValueError:
print("请输入有效的数字!")
# 获取输出目录路径
default_output_dir = input_dir + "_cropped"
output_dir = input(f"请输入输出目录路径 (默认: {default_output_dir}): ").strip().strip('"')
if not output_dir:
output_dir = default_output_dir
# 确认操作
print(f"\n即将批量处理 '{input_dir}' 目录下的所有图片")
print(f"从每张图片底部移除 {pixels_to_remove} 像素")
print(f"处理后的图片将保存到 '{output_dir}'")
confirm = input("\n确认执行?(y/n): ").strip().lower()
if confirm in ['y', 'yes', '是']:
print("\n正在处理...")
batch_crop_bottom_pixels(input_dir, output_dir, pixels_to_remove)
print("批量处理完成!")
else:
print("操作已取消。")
def main():
parser = argparse.ArgumentParser(description="从图片底部截去指定像素", add_help=False)
parser.add_argument("input", nargs='?', help="输入图片路径或目录")
parser.add_argument("-o", "--output", help="输出图片路径或目录")
parser.add_argument("-p", "--pixels", type=int, help="要从底部移除的像素数")
parser.add_argument("-b", "--batch", action="store_true", help="批量处理目录中的图片")
parser.add_argument("-h", "--help", action="help", help="显示帮助信息")
args = parser.parse_args()
# 如果提供了命令行参数,则使用命令行模式
if args.input or args.pixels:
# 检查必需参数
if not args.input:
print("错误: 请提供输入路径")
return
if not args.pixels:
print("错误: 请提供要移除的像素数 (-p/--pixels)")
return
# 检查输入路径是否存在
if not os.path.exists(args.input):
print(f"错误: 输入路径 {args.input} 不存在")
return
if args.batch:
# 批量处理模式
if not args.output:
print("批量处理模式需要指定输出目录")
return
if not os.path.isdir(args.input):
print("批量处理模式下输入路径必须是目录")
return
batch_crop_bottom_pixels(args.input, args.output, args.pixels)
else:
# 单文件处理模式
if not os.path.isfile(args.input):
print("单文件处理模式下输入路径必须是文件")
return
output_path = args.output if args.output else f"{args.input}_cropped{os.path.splitext(args.input)[1]}"
crop_bottom_pixels(args.input, output_path, args.pixels)
else:
# 否则进入交互式模式
interactive_mode()
if __name__ == "__main__":
main()
下载vscode
下载python解释器
配置解释器
pip install Pillow
拉库
ok!亲测可用
2225

被折叠的 条评论
为什么被折叠?



