本文目录导读:

我来为您提供几个批量处理照片方向的脚本方案,涵盖不同操作系统和使用场景:
Python脚本(跨平台)
基础版 - 按EXIF信息自动旋转
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量处理照片方向 - 根据EXIF信息自动旋转
"""
import os
import sys
from PIL import Image
from PIL import ImageOps
import piexif
def process_photo_exif(input_path, output_path=None):
"""使用EXIF信息处理照片方向"""
try:
img = Image.open(input_path)
# 获取EXIF数据
try:
exif = piexif.load(img.info.get('exif', b''))
orientation = exif.get('0th', {}).get(piexif.ImageIFD.Orientation, 1)
except:
orientation = 1
# 根据方向值旋转
if orientation == 3:
img = img.rotate(180, expand=True)
elif orientation == 6:
img = img.rotate(-90, expand=True)
elif orientation == 8:
img = img.rotate(90, expand=True)
# 删除方向EXIF标记(因为已经处理过了)
if orientation != 1:
try:
exif = piexif.load(img.info.get('exif', b''))
exif['0th'][piexif.ImageIFD.Orientation] = 1
exif_bytes = piexif.dump(exif)
# 保存
if output_path:
img.save(output_path, 'jpeg', exif=exif_bytes, quality=95)
else:
img.save(input_path, 'jpeg', exif=exif_bytes, quality=95)
return True
except:
pass
return True
except Exception as e:
print(f"处理失败 {input_path}: {str(e)}")
return False
def batch_process_exif(folder_path):
"""批量处理文件夹中的照片"""
supported_ext = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff']
for root, dirs, files in os.walk(folder_path):
for file in files:
if os.path.splitext(file)[1].lower() in supported_ext:
filepath = os.path.join(root, file)
print(f"正在处理: {filepath}")
process_photo_exif(filepath)
if __name__ == "__main__":
folder = input("请输入照片文件夹路径: ")
batch_process_exif(folder)
print("批量处理完成!")
增强版 - 支持自定义旋转角度
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量处理照片方向 - 支持自定义旋转和预览
"""
import os
import sys
from PIL import Image
import argparse
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
class PhotoRotator:
def __init__(self, root):
self.root = root
self.root.title("照片批量旋转工具")
self.root.geometry("500x300")
# 文件夹选择
tk.Label(root, text="选择文件夹:").pack(pady=5)
self.folder_var = tk.StringVar()
tk.Entry(root, textvariable=self.folder_var, width=50).pack(pady=5)
tk.Button(root, text="浏览", command=self.select_folder).pack(pady=5)
# 旋转角度选择
tk.Label(root, text="旋转角度:").pack(pady=5)
self.angle_var = tk.IntVar(value=0)
angle_frame = tk.Frame(root)
angle_frame.pack(pady=5)
for angle in [0, 90, 180, 270]:
tk.Radiobutton(angle_frame, text=f"{angle}°",
variable=self.angle_var, value=angle).pack(side=tk.LEFT, padx=5)
# 处理选项
self.overwrite_var = tk.BooleanVar(value=False)
tk.Checkbutton(root, text="覆盖原文件(不创建副本)",
variable=self.overwrite_var).pack(pady=5)
# 处理按钮
tk.Button(root, text="开始处理", command=self.process_photos,
bg="lightblue", font=("Arial", 12)).pack(pady=20)
# 进度条
self.progress = ttk.Progressbar(root, length=400)
self.progress.pack(pady=20)
def select_folder(self):
folder = filedialog.askdirectory()
if folder:
self.folder_var.set(folder)
def process_photos(self):
folder = self.folder_var.get()
if not folder:
messagebox.showerror("错误", "请选择文件夹!")
return
angle = self.angle_var.get()
overwrite = self.overwrite_var.get()
if angle == 0:
messagebox.showinfo("提示", "请选择旋转角度!")
return
# 处理逻辑
processed_count = 0
files = []
# 收集符合条件的文件
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
files.append(os.path.join(root, filename))
if not files:
messagebox.showwarning("警告", "没有找到图片文件!")
return
# 处理每个文件
self.progress['maximum'] = len(files)
for i, filepath in enumerate(files):
try:
img = Image.open(filepath)
if angle == 90:
img = img.rotate(-90, expand=True) # 顺时针旋转90度
elif angle == 180:
img = img.rotate(180, expand=True)
elif angle == 270:
img = img.rotate(90, expand=True) # 顺时针旋转270度
if overwrite:
img.save(filepath, quality=95)
else:
# 创建新文件
base, ext = os.path.splitext(filepath)
new_file = f"{base}_rotated{ext}"
img.save(new_file, quality=95)
print(f"已创建: {new_file}")
processed_count += 1
self.progress['value'] = i + 1
self.root.update()
except Exception as e:
print(f"处理失败 {filepath}: {str(e)}")
messagebox.showinfo("完成", f"成功处理 {processed_count} 个文件!")
def main():
root = tk.Tk()
app = PhotoRotator(root)
root.mainloop()
if __name__ == "__main__":
main()
Bash脚本(Linux/Mac,使用ImageMagick)
#!/bin/bash
# 批量处理照片方向 - 使用ImageMagick
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
echo "照片批量旋转工具"
echo "=================="
# 选择目录
echo "请输入要处理的目录路径:"
read directory
if [ ! -d "$directory" ]; then
echo -e "${RED}错误:目录不存在${NC}"
exit 1
fi
# 选择旋转方向
echo "选择旋转方向:"
echo "1) 顺时针90度"
echo "2) 逆时针90度"
echo "3) 180度"
read rotation
# 处理文件
count=0
total=$(find "$directory" -type f \( -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" \) | wc -l)
echo "找到 $total 个图片文件"
for file in $(find "$directory" -type f \( -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" \)); do
count=$((count + 1))
echo -ne "处理中: $count/$total - $(basename "$file")\r"
case $rotation in
1) convert "$file" -rotate 90 "$file" ;;
2) convert "$file" -rotate -90 "$file" ;;
3) convert "$file" -rotate 180 "$file" ;;
*)
echo -e "${RED}无效选择${NC}"
exit 1
;;
esac
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓${NC} - $file"
else
echo -e "${RED}✗${NC} - $file 处理失败"
fi
done
echo -e "\n${GREEN}处理完成!${NC}"
PowerShell脚本(Windows)
# 批量处理照片方向 - PowerShell版本
Add-Type -AssemblyName System.Drawing
$folderPath = Read-Host "请输入照片文件夹路径"
$rotation = Read-Host "输入旋转角度 (1=90°, 2=180°, 3=270°)"
if (-not (Test-Path $folderPath)) {
Write-Host "错误:文件夹不存在" -ForegroundColor Red
exit
}
$files = Get-ChildItem $folderPath -Include *.jpg,*.jpeg,*.png,*.bmp -Recurse
$count = 0
foreach ($file in $files) {
$count++
Write-Progress -Activity "处理照片" -Status "处理中 $($file.Name)" -PercentComplete (($count / $files.Count) * 100)
try {
$img = [System.Drawing.Image]::FromFile($file.FullName)
switch ($rotation) {
"1" { $img.RotateFlip([System.Drawing.RotateFlipType]::Rotate90FlipNone) }
"2" { $img.RotateFlip([System.Drawing.RotateFlipType]::Rotate180FlipNone) }
"3" { $img.RotateFlip([System.Drawing.RotateFlipType]::Rotate270FlipNone) }
}
$img.Save($file.FullName)
$img.Dispose()
Write-Host "✓ 已处理: $($file.Name)" -ForegroundColor Green
}
catch {
Write-Host "✗ 处理失败: $($file.Name) - $($_.Exception.Message)" -ForegroundColor Red
}
}
Write-Host "`n批量处理完成!" -ForegroundColor Cyan
使用方法
Python脚本:
# 安装依赖 pip install pillow piexif # 运行脚本 python photo_rotator.py
Bash脚本:
# 安装ImageMagick sudo apt-get install imagemagick # Ubuntu/Debian brew install imagemagick # MacOS # 赋予执行权限并运行 chmod +x photo_rotator.sh ./photo_rotator.sh
PowerShell脚本:
# 运行脚本 .\photo_rotator.ps1
注意事项
- 备份重要文件:在处理前建议先备份原始照片
- 测试模式:建议先在小批量文件上测试
- 处理复制品:可以选择输出到新目录而不是覆盖原图
- EXIF信息:某些脚本会保留或处理EXIF信息
选择最适合您需求的方案即可,如果只是简单使用,推荐Python的GUI版本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播