本文目录导读:

我来介绍几种用脚本转换图片格式的方法,涵盖不同语言和场景:
Python + Pillow (最常用)
安装依赖
pip install Pillow
单张图片转换
from PIL import Image
import os
def convert_image(input_path, output_format='PNG', output_path=None):
"""
转换单张图片格式
"""
try:
# 打开图片
img = Image.open(input_path)
# 如果没有指定输出路径,自动生成
if output_path is None:
base_name = os.path.splitext(input_path)[0]
output_path = f"{base_name}.{output_format.lower()}"
# 转换并保存
img.save(output_path, format=output_format)
print(f"转换成功: {input_path} -> {output_path}")
return True
except Exception as e:
print(f"转换失败: {e}")
return False
# 使用示例
# convert_image('image.jpg', 'PNG')
# convert_image('photo.png', 'JPEG', 'photo.jpg')
批量转换
from PIL import Image
import os
import glob
def batch_convert(input_dir, output_dir, input_formats, output_format):
"""
批量转换图片格式
Args:
input_dir: 输入目录
output_dir: 输出目录
input_formats: 输入格式列表,如 ['.jpg', '.png']
output_format: 输出格式,如 'WEBP'
"""
# 确保输出目录存在
os.makedirs(output_dir, exist_ok=True)
# 遍历所有输入格式
for fmt in input_formats:
files = glob.glob(os.path.join(input_dir, f'*{fmt}'))
files.extend(glob.glob(os.path.join(input_dir, f'*{fmt.upper()}')))
for file_path in files:
try:
# 打开图片
img = Image.open(file_path)
# 生成输出文件路径
base_name = os.path.splitext(os.path.basename(file_path))[0]
output_path = os.path.join(output_dir, f"{base_name}.{output_format.lower()}")
# 转换并保存
img.save(output_path, format=output_format)
print(f"转换: {file_path} -> {output_path}")
except Exception as e:
print(f"转换失败 {file_path}: {e}")
# 使用示例
# batch_convert('./images', './converted', ['.jpg', '.png'], 'WEBP')
Python + OpenCV
import cv2
import os
def convert_with_opencv(input_path, output_path):
"""
使用 OpenCV 转换图片格式
"""
try:
# 读取图片(OpenCV 默认使用 BGR 颜色空间)
img = cv2.imread(input_path)
if img is None:
print(f"无法读取图片: {input_path}")
return False
# 保存图片(根据扩展名自动选择格式)
cv2.imwrite(output_path, img)
print(f"转换成功: {input_path} -> {output_path}")
return True
except Exception as e:
print(f"转换失败: {e}")
return False
# 使用示例
# convert_with_opencv('image.jpg', 'image.png')
Bash/shell 脚本 (Linux/Mac)
#!/bin/bash
# convert_images.sh
# 使用 ImageMagick
convert_imagemagick() {
input_file="$1"
output_file="$2"
convert "$input_file" "$output_file"
}
# 批量转换 JPG 到 PNG
batch_jpg_to_png() {
input_dir="$1"
output_dir="$2"
mkdir -p "$output_dir"
for file in "$input_dir"/*.jpg "$input_dir"/*.jpeg; do
if [ -f "$file" ]; then
basename=$(basename "$file")
name="${basename%.*}"
convert "$file" "$output_dir/$name.png"
echo "转换: $file -> $output_dir/$name.png"
fi
done
}
# 使用示例
# convert_imagemagick 'image.jpg' 'image.png'
# batch_jpg_to_png './images' './converted'
Node.js + sharp (高性能)
// convert.js
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
async function convertImage(inputPath, outputFormat, outputPath) {
try {
// 确定输出格式对应的扩展名
const extMap = {
'jpeg': '.jpg',
'png': '.png',
'webp': '.webp',
'gif': '.gif'
};
if (!outputPath) {
const baseName = path.parse(inputPath).name;
outputPath = `./${baseName}${extMap[outputFormat] || '.' + outputFormat}`;
}
// 使用 sharp 转换
await sharp(inputPath)
.toFormat(outputFormat)
.toFile(outputPath);
console.log(`转换成功: ${inputPath} -> ${outputPath}`);
} catch (error) {
console.error('转换失败:', error);
}
}
// 批量转换
async function batchConvert(inputDir, outputDir, outputFormat) {
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const files = fs.readdirSync(inputDir)
.filter(file => /\.(jpg|jpeg|png|gif)$/i.test(file));
for (const file of files) {
const inputPath = path.join(inputDir, file);
const outputName = path.parse(file).name + '.' + outputFormat;
const outputPath = path.join(outputDir, outputName);
await convertImage(inputPath, outputFormat, outputPath);
}
}
// 使用
// batchConvert('./images', './output', 'webp');
命令行工具对比
| 工具 | 安装 | 示例 |
|---|---|---|
| ImageMagick | apt install imagemagick |
convert image.jpg image.png |
| ffmpeg | apt install ffmpeg |
ffmpeg -i input.jpg output.png |
| cwebp | apt install webp |
cwebp image.png -o image.webp |
| pngquant | apt install pngquant |
pngquant input.png --output output.png |
高级功能示例
# 带图片压缩和质量控制的转换
from PIL import Image
import os
def convert_with_quality(input_path, output_path, quality=85, max_size=(1920, 1080)):
"""
转换图片并调整质量
"""
try:
img = Image.open(input_path)
# 调整图片大小
img.thumbnail(max_size, Image.Resampling.LANCZOS)
# 根据输出格式设置参数
ext = os.path.splitext(output_path)[1].lower()
save_options = {
'quality': quality, # JPEG/WEBP 质量
'optimize': True, # 优化文件大小
'progressive': True # 渐进式 JPEG
}
# RGB 转换(处理 PNG 带透明通道转 JPEG)
if ext in ['.jpg', '.jpeg'] and img.mode in ['RGBA', 'P']:
img = img.convert('RGB')
img.save(output_path, **save_options)
print(f"转换成功: {os.path.basename(input_path)}")
except Exception as e:
print(f"转换失败 {input_path}: {e}")
# 批量转换并压缩
def batch_compress(input_dir, output_dir, quality=80):
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir,
f"compressed_{os.path.splitext(filename)[0]}.jpg")
convert_with_quality(input_path, output_path, quality)
使用建议
- 简单场景:使用 Python + Pillow,代码简单易维护
- 高性能/大批量:使用 Node.js + sharp 或 Python + OpenCV
- 命令行快捷:使用 ImageMagick
- Web 优化:转换为 WEBP 格式,配合质量参数
最常见的 WebP 转换命令:
# 单张
python3 -c "from PIL import Image; Image.open('input.jpg').save('output.webp', quality=80)"
# 批量
find . -name "*.jpg" -exec python3 -c "from PIL import Image; import sys; Image.open('{}').save('{}'.replace('.jpg','.webp'), quality=80)" \;
选择哪种方法取决于你的具体需求(性能、批量、格式支持等),需要我详细展开某个特定场景吗?