🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【复制粘贴即可】用Python批量调整图片大小!面向Web开发者的Pillow入门教程

你好!几个月前我还是个编程小白,本系列将以我借助AI搭建网站的经验,从初学者的视角进行解说。

在运营网站时,几乎总会遇到一个任务,那就是“调整图片大小”。博客文章的缩略图、商品图片、作品集里的作品……手动一张一张地调整大量图片的尺寸,说实话,这过程足以让人崩溃,对吧?我也经历过。

不过,请放心。使用Python,这样繁琐的工作只需几秒钟就能实现自动化!在本文中,我将结合自己曾遇到的难题,详细解说如何制作一个即使是编程初学者也能通过复制粘贴立即可用的“批量图片尺寸调整工具”。希望你也能体验到那种“成功运行了!”的激动之情。


本次目标:自动化繁琐的图片尺寸调整工作!

读完本文,你将能制作出这样一个Python脚本:

例如,你可以瞬间将文件夹里几十张照片,转换为适合博客的800像素宽度的图片。再也不需要反复打开图片编辑软件了!

调整尺寸前后的图片对比。左侧是多张原始的大尺寸照片,右侧是多张经过Python程序批量调整尺寸后的小图片。

告别手动操作!使用Python批量处理的示意图。


准备工作:安装Pillow并设置工作文件夹

在念出魔法咒语之前,我们先来做些准备工作。别担心,这并不难。

1. Pillow是什么?如何安装?

我们这次的主角是一个名为“Pillow”的库。库就像一个装满了便利功能的“工具箱”。而Pillow,可以说是用Python处理图片的“图像处理大师工具箱”。

Pillow是一个非常可靠的库,被世界各地的许多开发者使用。它的官方网站上有丰富的文档,你可以放心使用。(参考:Pillow官方文档

安装非常简单,只需在命令提示符(Windows)或终端(Mac)中运行下面这一行命令即可。

pip install Pillow

2. 准备工作文件夹

接下来,我们来准备一个工作文件夹。这一点非常重要!为了避免混乱,我们把存放原始图片的文件夹和存放调整后图片的文件夹分开。

首先,在桌面等任意你喜欢的位置,创建一个名为“resize_tool”的文件夹。然后,在里面创建以下三项内容:

  1. input_images 文件夹: 这里用来存放你想要调整尺寸的原始图片。
  2. output_images 文件夹: 这里用来存放调整尺寸后的图片。
  3. resize.py: 这是我们即将编写的Python代码文件。

目录结构如下所示:

resize_tool/
├── input_images/
│   ├── photo1.jpg
│   ├── photo2.png
│   └── ... (将要调整大小的图片放在这里)
│
├── output_images/
│   └── (这里一开始是空的)
│
└── resize.py (我们将创建这个文件)

准备工作到此结束!请在你自己的 `input_images` 文件夹里放几张图片吧。


实践环节:开始编写Python代码!

终于到了编码时间!用你的文本编辑器打开 `resize.py` 文件,我们一起来编写吧。我会把每个步骤都拆解开来讲解,请不要着急,跟上我的步伐。

第一步:准备必要的工具(模块)

首先,在程序的开头,我们需要声明“这次我们要使用这些工具”。让我们来调用图像处理大师“Pillow”和文件/文件夹处理专家“os”。

import os
from PIL import Image

from PIL import Image 的意思是,“从Pillow库(PIL)中,我们特别要使用处理图像(Image)的功能”。把它当作一句标准的咒语来记就行了。


第二步:告诉程序文件夹的位置

接下来,我们需要告诉程序我们刚才准备的“输入文件夹”和“输出文件夹”在哪里。

# 指定输入和输出文件夹的路径
input_dir = 'input_images'
output_dir = 'output_images'

这样一来,程序就知道应该从 `input_images` 读取图片,并将处理结果写入 `output_images` 了。


第三步:尝试调整一张图片(基本流程)

一下子处理所有图片可能会让人困惑,所以我们先来看看调整“单张图片”的流程。这是所有操作的基础。

  1. 打开图片 (`Image.open`)
  2. 调整为新尺寸 (`.resize`)
  3. 用新名字保存 (`.save`)

用代码表示大概是这样。(※ 这段代码暂时还不用运行)

# (这只是一个概念示例)
# 1. 打开图片
img = Image.open('input_images/photo1.jpg')

# 2. 调整宽度为800px (高度暂时随意)
resized_img = img.resize((800, 600))

# 3. 另存为新文件
resized_img.save('output_images/resized_photo1.jpg')

第四步:依次处理输入文件夹中的所有图片

了解了基础之后,就到了正题。我们让Python从 `input_images` 文件夹中逐个取出文件,并依次对它们进行尺寸调整。这种“循环处理”正是编程的强项。

使用 `os.listdir(input_dir)` 可以获取指定文件夹内所有文件的文件名列表。我们将用它来重复处理,直到没有文件为止。

# 遍历输入目录中的所有文件
for filename in os.listdir(input_dir):
    # 针对每个文件的尺寸调整逻辑将写在这里
    print(f"正在处理 {filename}...")

for ... in ...: 是用于创建循环的语法。它会从 `os.listdir(input_dir)` 获取的文件名列表中,逐个取出文件名并赋给名为 `filename` 的变量,然后执行代码块内的操作。


[至关重要] 我曾踩过的坑及解决方案

看起来进展顺利,但这里其实有一个初学者很容易掉进去的坑。我就曾华丽地踩过!

问题:脚本试图处理非图片文件而导致崩溃!

如果你用的是Mac,系统会自动生成像 `.DS_Store` 这样的隐藏文件。你也可能自己放了一些用于记录的文本文件。之前的代码会尝试处理文件夹中的“所有”文件,所以当它试图打开一个不是图片的文件时,就会报错。

解决方案:只处理图片文件(如.jpg, .png等)

我们添加一个条件判断,检查文件名的末尾(扩展名),只有当它是图片格式时才执行调整尺寸的操作。这样就能可靠地避免错误。

for filename in os.listdir(input_dir):
    # 检查文件扩展名是否为 .jpg, .jpeg, .png, 或 .gif 之一
    if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')):
        # 如果尺寸调整逻辑写在这里,就只会处理图片文件!
        print(f"正在处理图片文件: {filename}")
    else:
        # 如果不是图片文件,则跳过
        print(f"跳过非图片文件: {filename}")
        continue # 进入循环的下一次迭代

关键是在检查文件末尾之前,用 .lower() 将文件名转换为小写,然后再用 .endswith() 来检查。这样就能兼容像 `PHOTO.JPG` 这样的大写扩展名了。


进阶技巧一:保持宽高比,优雅地调整尺寸

好了,我们掌握了调整尺寸的基础,但如果只是简单地指定尺寸,图片可能会被纵向或横向拉伸,变得很难看。为了保持网站的质量,保持宽高比是必不可少的

计算很简单。我们只需要计算出原始图片的宽高比,然后根据新的宽度自动计算出新的高度即可。

  1. 确定目标宽度 (例如: 800px)
  2. 获取原始图片的尺寸 (宽度和高度)
  3. 用 `原始高度 / 原始宽度` 计算出宽高比
  4. 用 `新高度 = 目标宽度 * 宽高比` 得出新的高度

转换成代码后如下所示:

# (这段代码要放在循环里)

# 打开原始图片
img = Image.open(os.path.join(input_dir, filename))
width, height = img.size # 获取原始的宽度和高度

# 指定新的宽度
new_width = 800
# 在保持宽高比的同时计算新的高度
new_height = int(new_width * height / width)

# 执行调整!
resized_img = img.resize((new_width, new_height))

使用 os.path.join() 可以安全地将文件夹名和文件名正确地组合起来,适用于任何操作系统。另外,由于计算结果可能是小数,我们用 `int()` 将它转换为整数。


进阶技巧二:给Web开发者的福利!添加图片水印

有时候你可能想添加“水印”,以防止你的作品或博客图片被未经许可盗用。用Pillow,这也很容易。我们来给调整尺寸后的图片添加版权声明等文字吧。

为此,我们将使用Pillow的绘图功能 `ImageDraw`。

# (这是调整尺寸后的处理)
from PIL import ImageDraw, ImageFont

# ... 在调整尺寸过程之后 ...

# 创建一个绘图对象
draw = ImageDraw.Draw(resized_img)

# 指定文本和字体
text = "© Your Name"
# 你可以指定你电脑上安装的字体。如果找不到,将使用默认字体。
try:
    font = ImageFont.truetype("arial.ttf", 24)
except IOError:
    font = ImageFont.load_default()

# 计算绘制文本的位置 (右下角)
text_width, text_height = draw.textbbox((0, 0), text, font=font)[2:4]
position = (resized_img.width - text_width - 10, resized_img.height - text_height - 10)

# 绘制文本
draw.text(position, text, font=font, fill=(255, 255, 255, 128)) # 半透明白色

# 之后再保存图片

这可能看起来有点复杂,但流程很简单,就是“切换到绘图模式”、“确定文本和位置”,然后“写入”。`fill=(255, 255, 255, 128)` 中最后的 `128` 代表不透明度,你可以在0(完全透明)到255(完全不透明)之间进行调整。


[AI妙用] 如何让AI写出这段代码?

在我学习编程的过程中,像ChatGPT和Gemini这样的AI是必不可少的。如果你给它们正确的指令(prompt),它们可以瞬间生成像这样的代码。

例如,可以这样请求:

请使用Python的Pillow库创建一个批量调整图片尺寸的脚本。 # 要求 - 从名为 `input_images` 的文件夹中读取图片。 - 只处理扩展名为 `.jpg`, `.jpeg`, 和 `.png` 的文件。 - 将所有图片调整为800像素宽,同时保持宽高比。 - 将调整后的图片保存到名为 `output_images` 的文件夹中,并使用原始文件名。 - 请在控制台显示正在处理的文件名。

关键在于具体且清晰地用列表形式传达你的需求。AI是出色的助手,你的指令越精确,它返回的代码就越准确。


整合:完整可运行的批量图片尺寸调整工具的全部代码

久等了!这是最终版本的Python脚本,它结合了我们讨论过的所有元素。把它复制粘贴到 `resize.py` 文件中,在你的 `input_images` 文件夹里放几张图片,然后运行它试试吧。

要运行它,只需在你的命令提示符或终端中导航到 `resize_tool` 文件夹,然后输入 `python resize.py`。

import os
from PIL import Image

def resize_images_in_folder(input_dir, output_dir, new_width=800):
    """
    一个批量调整指定文件夹内图片大小
    并保持宽高比的函数。
    
    :param input_dir: 输入文件夹的路径
    :param output_dir: 输出文件夹的路径
    :param new_width: 调整后图片的目标宽度(像素)
    """
    # 如果输出文件夹不存在,则创建它
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
        print(f"已创建文件夹: '{output_dir}'")

    # 支持的图片扩展名列表
    supported_formats = ('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff')

    # 获取输入目录中的所有文件
    filenames = os.listdir(input_dir)
    
    if not filenames:
        print(f"输入文件夹 '{input_dir}' 为空。")
        return

    print(f"开始处理... 待检查文件数: {len(filenames)}")

    # 处理每个文件
    for filename in filenames:
        # 检查文件格式是否受支持
        if not filename.lower().endswith(supported_formats):
            print(f"--- 跳过: {filename} (不支持的文件类型)")
            continue

        try:
            # 创建完整的输入和输出路径
            input_path = os.path.join(input_dir, filename)
            output_path = os.path.join(output_dir, filename)

            # 打开图片
            with Image.open(input_path) as img:
                # 获取原始图片的宽度和高度
                width, height = img.size
                
                # 在保持宽高比的同时计算新的高度
                aspect_ratio = height / width
                new_height = int(new_width * aspect_ratio)

                # 调整图片大小
                resized_img = img.resize((new_width, new_height))
                
                # 保存图片 (为PNG保持透明度)
                if filename.lower().endswith('.png'):
                    resized_img.save(output_path, 'PNG')
                else:
                    # 对于JPEG,可以指定质量 (默认为75)
                    # 转换为RGB以防止保存JPEG时出错
                    resized_img.convert('RGB').save(output_path, 'JPEG', quality=90)

                print(f"✓ 成功: 已将 {filename} 调整为 {new_width}x{new_height}")

        except Exception as e:
            print(f"× 错误: 处理 {filename} 时发生问题 - {e}")

    print("所有处理已完成。")

# --- 程序执行从这里开始 ---
if __name__ == "__main__":
    # 指定输入和输出文件夹的路径
    INPUT_FOLDER = 'input_images'
    OUTPUT_FOLDER = 'output_images'
    
    # 指定调整尺寸的目标宽度
    TARGET_WIDTH = 800

    # 运行函数
    resize_images_in_folder(INPUT_FOLDER, OUTPUT_FOLDER, TARGET_WIDTH)

打开 `output_images` 文件夹看看吧。如果你看到一整排调整好尺寸的图片,那就大功告成了!


最后:编程是解决“繁琐”问题的魔法

这次,我们用Python和Pillow创建了一个工具来自动化枯燥的图片尺寸调整工作。编程听起来可能很难,但当你有一个像“解决我身边的繁琐问题”这样的目标时,它立刻就变得有趣,并成为一项非常实用的技能。

如果本文能让你体验到“我做到了!”的成功,并成为你进入编程世界的第一步,我将感到非常高兴。请务必尝试不同的设置,把它改造成你自己的专属工具吧!


下一步

通过本文体验到Python的便利之后,你肯定渴望进入下一步。下一次,何不尝试连接外部服务,做些更有趣的事情呢?

下面的文章讲解了如何使用Web API创建一个获取天气预报的命令行应用。让我们利用今天学到的知识,向着更高的技能目标前进吧!

用Python创建一个CLI天气应用 (API使用)