本文目录导读:

使用 Python + Pillow 库
import os
from PIL import Image
import glob
def batch_create_thumbnails(input_dir, output_dir, size=(150, 150)):
"""批量生成缩略图"""
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 支持的图片格式
formats = ['*.jpg', '*.jpeg', '*.png', '*.gif', '*.bmp']
for format in formats:
for img_path in glob.glob(os.path.join(input_dir, format)):
try:
# 打开图片
img = Image.open(img_path)
# 生成缩略图(保持宽高比)
img.thumbnail(size, Image.Resampling.LANCZOS)
# 生成输出文件名
filename = os.path.basename(img_path)
output_path = os.path.join(output_dir, f"thumb_{filename}")
# 保存缩略图
img.save(output_path, optimize=True)
print(f"已生成: {output_path}")
except Exception as e:
print(f"处理 {img_path} 时出错: {e}")
# 使用示例
batch_create_thumbnails("./images", "./thumbnails", size=(200, 200))
使用 ImageMagick (命令行)
# 批量转换当前目录所有jpg为缩略图
for img in *.jpg; do
convert "$img" -thumbnail 200x200 "thumb_$img"
done
# 或使用 mogrify(直接修改)
mogrify -path thumbnails/ -thumbnail 200x200 *.jpg
# 递归处理子目录
find . -name "*.jpg" -exec convert {} -thumbnail 200x200 thumbnails/{} \;
Node.js + Sharp 库
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
async function batchCreateThumbnails(inputDir, outputDir, size = 200) {
// 创建输出目录
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const files = fs.readdirSync(inputDir);
const imageFormats = ['.jpg', '.jpeg', '.png', '.webp', '.gif'];
for (const file of files) {
const ext = path.extname(file).toLowerCase();
if (imageFormats.includes(ext)) {
try {
const inputPath = path.join(inputDir, file);
const outputPath = path.join(outputDir, `thumb_${file}`);
await sharp(inputPath)
.resize(size, size, {
fit: 'cover',
position: 'centre'
})
.toFile(outputPath);
console.log(`已生成: ${outputPath}`);
} catch (error) {
console.error(`处理 ${file} 时出错:`, error);
}
}
}
}
// 使用示例
batchCreateThumbnails('./images', './thumbnails', 200);
使用 FFmpeg (视频缩略图)
# 批量生成视频缩略图
for video in *.mp4; do
ffmpeg -i "$video" -ss 00:00:05 -vframes 1 -q:v 2 "thumb_${video%.*}.jpg"
done
# 生成多个缩略图
for video in *.mp4; do
ffmpeg -i "$video" -vf "fps=1/10,scale=320:180" "thumb_${video%.*}_%03d.jpg"
done
PHP 批量生成
<?php
function batchCreateThumbnails($inputDir, $outputDir, $width = 150, $height = 150) {
if (!file_exists($outputDir)) {
mkdir($outputDir, 0777, true);
}
$files = glob($inputDir . '/*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($files as $file) {
$filename = basename($file);
$thumbPath = $outputDir . '/thumb_' . $filename;
list($origWidth, $origHeight, $type) = getimagesize($file);
// 计算缩放比例
$ratio = min($width / $origWidth, $height / $origHeight);
$newWidth = (int)($origWidth * $ratio);
$newHeight = (int)($origHeight * $ratio);
// 创建新图像
switch ($type) {
case IMAGETYPE_JPEG:
$src = imagecreatefromjpeg($file);
$thumb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thumb, $src, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
imagejpeg($thumb, $thumbPath, 85);
break;
case IMAGETYPE_PNG:
$src = imagecreatefrompng($file);
$thumb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thumb, $src, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
imagepng($thumb, $thumbPath, 9);
break;
}
imagedestroy($src);
imagedestroy($thumb);
echo "已生成: $thumbPath\n";
}
}
batchCreateThumbnails('./images', './thumbnails', 200, 200);
?>
批量处理的最佳实践
import os
from PIL import Image
import concurrent.futures
from pathlib import Path
class ThumbnailGenerator:
def __init__(self, input_dir, output_dir, size=(150, 150), quality=85):
self.input_dir = Path(input_dir)
self.output_dir = Path(output_dir)
self.size = size
self.quality = quality
self.supported_formats = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'}
# 创建输出目录
self.output_dir.mkdir(parents=True, exist_ok=True)
def process_image(self, img_path):
"""处理单个图片"""
try:
img = Image.open(img_path)
# 生成缩略图
img.thumbnail(self.size, Image.Resampling.LANCZOS)
# 生成输出路径
output_path = self.output_dir / f"thumb_{img_path.name}"
# 根据格式保存
if img_path.suffix.lower() in ['.jpg', '.jpeg']:
img.save(output_path, 'JPEG', quality=self.quality)
else:
img.save(output_path, optimize=True)
return f"成功: {output_path}"
except Exception as e:
return f"失败: {img_path} - {str(e)}"
def generate_all(self, max_workers=4):
"""并行生成所有缩略图"""
images = []
# 收集所有图片
for fmt in self.supported_formats:
images.extend(self.input_dir.glob(f'*{fmt}'))
images.extend(self.input_dir.glob(f'*{fmt.upper()}'))
if not images:
print("未找到图片文件")
return
# 多线程处理
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
results = executor.map(self.process_image, images)
for result in results:
print(result)
# 使用示例
generator = ThumbnailGenerator(
input_dir="./images",
output_dir="./thumbnails",
size=(200, 200),
quality=90
)
generator.generate_all(max_workers=8)
使用建议:
-
选择合适的工具:
- 简单需求:Python Pillow 或命令行 ImageMagick
- 高性能需求:Sharp (Node.js) 或 ImageMagick
- Web 服务:PHP GD 或 Imagick
-
性能优化:
- 使用多线程/进程处理大量图片
- 设置合适的缓存
- 选择合适的压缩质量
-
注意事项:
- 保持原始图片备份
- 注意版权问题
- 考虑使用渐进式加载
根据你的具体需求和使用环境选择合适的方案即可。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播