python -m pip install Pillow
from pathlib import Path
from PIL import Image, ImageSequence, ImageFilter
INPUT_FOLDER = r"D:\images"
OUTPUT_FOLDER = r"D:\images_upscaled"
SCALE_FACTOR = 2
OVERWRITE = False
SUPPORTED_EXTENSIONS = {".png", ".gif"}
def upscale_rgba_image(image, scale_factor, sharpen=True):
new_size = (image.width * scale_factor, image.height * scale_factor)
enlarged = image.resize(new_size, Image.Resampling.LANCZOS)
if sharpen:
enlarged = enlarged.filter(
ImageFilter.UnsharpMask(
radius=1.2,
percent=130,
threshold=2
)
)
return enlarged
def process_png(input_path, output_path, scale_factor):
with Image.open(input_path) as image:
original_size = image.size
image = image.convert("RGBA")
enlarged = upscale_rgba_image(
image,
scale_factor,
sharpen=True
)
enlarged.save(
output_path,
compress_level=6
)
print(
f"成功:{input_path.name} "
f"{original_size[0]}×{original_size[1]} -> "
f"{enlarged.width}×{enlarged.height}"
)
def process_gif(input_path, output_path, scale_factor):
with Image.open(input_path) as image:
original_size = image.size
loop = image.info.get("loop", 0)
frames = []
durations = []
previous = Image.new(
"RGBA",
image.size,
(0, 0, 0, 0)
)
for frame in ImageSequence.Iterator(image):
frame_rgba = frame.convert("RGBA")
composed = previous.copy()
composed.alpha_composite(frame_rgba)
enlarged = upscale_rgba_image(
composed,
scale_factor,
sharpen=True
)
frames.append(enlarged)
durations.append(
frame.info.get(
"duration",
image.info.get("duration", 100)
)
)
previous = composed
if not frames:
raise ValueError("GIF 中没有可处理的帧")
frames[0].save(
output_path,
save_all=True,
append_images=frames[1:],
duration=durations,
loop=loop,
optimize=False,
disposal=2
)
print(
f"成功:{input_path.name} "
f"{original_size[0]}×{original_size[1]} -> "
f"{original_size[0] * scale_factor}×"
f"{original_size[1] * scale_factor}"
)
def process_image(input_path, output_path, scale_factor):
suffix = input_path.suffix.lower()
if suffix == ".png":
process_png(
input_path,
output_path,
scale_factor
)
elif suffix == ".gif":
process_gif(
input_path,
output_path,
scale_factor
)
else:
raise ValueError(
f"不支持的格式:{suffix}"
)
def main():
input_folder = Path(INPUT_FOLDER)
output_folder = Path(OUTPUT_FOLDER)
if not input_folder.exists():
print(
f"错误:输入文件夹不存在:"
f"{input_folder}"
)
return
output_folder.mkdir(
parents=True,
exist_ok=True
)
image_files = [
path
for path in input_folder.iterdir()
if path.is_file()
and path.suffix.lower() in SUPPORTED_EXTENSIONS
]
if not image_files:
print(
"输入文件夹中没有找到 PNG 或 GIF 图片。"
)
return
success_count = 0
skipped_count = 0
failed_count = 0
print(f"共找到 {len(image_files)} 张图片")
print(f"放大倍数:{SCALE_FACTOR} 倍\n")
for input_path in image_files:
output_path = output_folder / input_path.name
if output_path.exists() and not OVERWRITE:
print(
f"跳过:{output_path.name} 已存在"
)
skipped_count += 1
continue
try:
process_image(
input_path,
output_path,
SCALE_FACTOR
)
success_count += 1
except Exception as error:
print(
f"失败:{input_path.name},"
f"原因:{error}"
)
failed_count += 1
print("\n处理完成")
print(f"成功:{success_count}")
print(f"跳过:{skipped_count}")
print(f"失败:{failed_count}")
print(f"输出文件夹:{output_folder}")
if __name__ == "__main__":
main()
INPUT_FOLDER = r"D:\images"
OUTPUT_FOLDER = r"D:\images_upscaled"
SCALE_FACTOR = 2