最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python+Pillow開發(fā)一個圖片批量格式轉換工具

 更新時間:2026年05月11日 09:17:33   作者:yuanpan  
在日常辦公、數(shù)據(jù)處理、網(wǎng)站開發(fā)和圖像處理學習中,經(jīng)常會遇到圖片格式轉換需求,如果圖片數(shù)量很少,可以使用圖像編輯軟件手動轉換,但當圖片數(shù)量達到幾十張、幾百張甚至更多時,手動操作就非常低效,所以本文介紹了使用Python+Pillow開發(fā)一個圖片批量格式轉換工具

引言

在日常辦公、數(shù)據(jù)處理、網(wǎng)站開發(fā)和圖像處理學習中,經(jīng)常會遇到圖片格式轉換需求,例如:

  • 將 JPG 圖片批量轉換為 PNG
  • 將 PNG 圖片批量轉換為 JPG
  • 壓縮圖片體積,方便上傳或傳輸
  • 批量調整圖片尺寸
  • 處理整個目錄下的圖片文件

如果圖片數(shù)量很少,可以使用圖像編輯軟件手動轉換。但當圖片數(shù)量達到幾十張、幾百張甚至更多時,手動操作就非常低效。Python 的 Pillow 庫可以很好地解決這個問題。

本文面向 Python 圖像處理入門者,使用 Pillow 實現(xiàn)一個簡易的圖片批量格式轉換工具。

一、Pillow 是什么

Pillow 是 Python 中最常用的圖像處理庫之一,它是 PIL 的現(xiàn)代維護版本。

PIL 的全稱是 Python Imaging Library,但原始 PIL 已經(jīng)停止維護。現(xiàn)在實際項目中通常安裝和使用的是 Pillow,不過導入時仍然使用:

from PIL import Image

Pillow 支持常見圖像處理操作,例如:

  • 打開圖片
  • 保存圖片
  • 圖片格式轉換
  • 圖片壓縮
  • 圖片縮放
  • 圖片裁剪
  • 圖片旋轉
  • 添加水印
  • 獲取圖片尺寸和模式

對于 Python 圖像處理入門者來說,Pillow 是非常適合練手的庫。

二、Pillow 安裝

使用 pip 安裝:

pip install pillow

如果使用的是國內(nèi)網(wǎng)絡環(huán)境,也可以指定鏡像源:

pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple

驗證是否安裝成功:

from PIL import Image

print(Image.__version__)

如果可以正常輸出版本號,說明 Pillow 安裝成功。

三、打開和查看圖片信息

在做格式轉換之前,先看一下如何讀取圖片基本信息。

from PIL import Image

image_path = "demo.jpg"

with Image.open(image_path) as img:
    print(f"圖片格式:{img.format}")
    print(f"圖片尺寸:{img.size}")
    print(f"圖片模式:{img.mode}")

常見的圖片模式包括:

  • RGB:常見彩色 圖片模式
  • RGBA:帶透明通道的圖片模式
  • L:灰度圖模式
  • P:調色板模式

理解圖片模式很重要,尤其是在 PNG 轉 JPG 時。因為 JPG 不支持透明通道,如果直接保存 RGBA 圖片為 JPG,可能會報錯。

四、JPG 轉 PNG

JPG 轉 PNG 的核心邏輯非常簡單:打開 JPG 文件,然后保存為 PNG 文件。

from PIL import Image

input_path = "demo.jpg"
output_path = "demo.png"

with Image.open(input_path) as img:
    img.save(output_path, "PNG")

print("JPG 轉 PNG 完成")

如果希望統(tǒng)一轉換為 RGB 模式,可以寫成:

from PIL import Image

with Image.open("demo.jpg") as img:
    img = img.convert("RGB")
    img.save("demo.png", "PNG")

PNG 是無損格式,適合保存截圖、圖標、透明背景圖片等。但 PNG 文件體積通常比 JPG 更大。

五、PNG 轉 JPG

PNG 轉 JPG 時,需要特別注意透明通道。

JPG 不支持透明背景,如果 PNG 是 RGBA 模式,需要先轉換為 RGB

from PIL import Image

input_path = "demo.png"
output_path = "demo.jpg"

with Image.open(input_path) as img:
    img = img.convert("RGB")
    img.save(output_path, "JPEG")

print("PNG 轉 JPG 完成")

如果 PNG 圖片帶透明背景,直接 convert("RGB") 可能會把透明區(qū)域變成黑色。更穩(wěn)妥的方式是先創(chuàng)建一個白色背景,再把 PNG 貼上去。

from PIL import Image

input_path = "logo.png"
output_path = "logo.jpg"

with Image.open(input_path) as img:
    if img.mode in ("RGBA", "LA"):
        background = Image.new("RGB", img.size, (255, 255, 255))
        background.paste(img, mask=img.getchannel("A"))
        background.save(output_path, "JPEG")
    else:
        img.convert("RGB").save(output_path, "JPEG")

print("PNG 轉 JPG 完成")

這種處理方式更適合批量轉換,因為它能兼容透明 PNG。

六、圖片壓縮

圖片壓縮通常用于減小文件體積。對于 JPG 圖片,可以通過 quality 參數(shù)控制質量。

from PIL import Image

input_path = "demo.jpg"
output_path = "demo_compressed.jpg"

with Image.open(input_path) as img:
    img = img.convert("RGB")
    img.save(output_path, "JPEG", quality=70, optimize=True)

print("圖片壓縮完成")

參數(shù)說明:

  • quality:圖片質量,取值一般為 1 到 95,數(shù)值越大質量越高,文件越大
  • optimize=True:讓 Pillow 盡量優(yōu)化保存結果

常用建議:

  • 文章配圖可以使用 quality=75
  • 縮略圖可以使用 quality=60
  • 高清存檔可以使用 quality=90

PNG 也可以壓縮:

from PIL import Image

with Image.open("demo.png") as img:
    img.save("demo_compressed.png", "PNG", optimize=True)

需要注意的是,PNG 是無損格式,單純使用 Pillow 壓縮時,體積下降不一定明顯。如果對 PNG 壓縮要求很高,可以結合專門的壓縮工具。

七、圖片尺寸調整

調整圖片尺寸可以使用 resize()。

from PIL import Image

input_path = "demo.jpg"
output_path = "demo_resized.jpg"

with Image.open(input_path) as img:
    resized = img.resize((800, 600))
    resized.save(output_path)

print("圖片尺寸調整完成")

不過直接指定固定寬高可能導致圖片變形。實際項目中更常見的是按比例縮放。

from PIL import Image

def resize_keep_ratio(img, max_width, max_height):
    img_copy = img.copy()
    img_copy.thumbnail((max_width, max_height))
    return img_copy

with Image.open("demo.jpg") as img:
    resized = resize_keep_ratio(img, 800, 800)
    resized.save("demo_resized.jpg")

thumbnail() 會保持原圖比例,并確保圖片不會超過指定的最大寬高。

例如,原圖是 3000 x 2000,最大尺寸設置為 800 x 800,縮放后會變成 800 x 533,不會被拉伸變形。

八、批量處理整個目錄

批量處理目錄的核心思路:

  1. 遍歷輸入目錄下的文件
  2. 判斷文件后綴是否為圖片格式
  3. 使用 Pillow 打開圖片
  4. 根據(jù)目標格式轉換并保存
  5. 遇到異常時跳過并打印錯誤信息

可以先寫一個簡單版本:

from pathlib import Path
from PIL import Image

input_dir = Path("input_images")
output_dir = Path("output_images")
output_dir.mkdir(parents=True, exist_ok=True)

for image_path in input_dir.iterdir():
    if image_path.suffix.lower() not in [".jpg", ".jpeg", ".png", ".bmp", ".webp"]:
        continue

    output_path = output_dir / f"{image_path.stem}.png"

    with Image.open(image_path) as img:
        img.save(output_path, "PNG")

    print(f"已轉換:{image_path.name} -> {output_path.name}")

這個版本可以完成基本批量轉換,但還不夠靈活。下面我們會封裝成一個完整工具。

九、完整代碼案例:圖片批量格式轉換工具

下面的完整代碼支持:

  • JPG、PNG、BMP、WEBP 等常見圖片格式輸入
  • 輸出為 JPG、PNG、WEBP
  • 可選圖片壓縮質量
  • 可選最大寬高,保持比例縮放
  • 批量處理整個目錄
  • 自動創(chuàng)建輸出目錄
  • 兼容 PNG 透明通道轉 JPG 的情況

保存為 batch_image_converter.py。

import argparse
from pathlib import Path

from PIL import Image


SUPPORTED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".bmp", ".webp", ".tif", ".tiff"}
SUPPORTED_OUTPUT_FORMATS = {"jpg", "jpeg", "png", "webp"}


def normalize_format(output_format):
    output_format = output_format.lower().strip(".")
    if output_format not in SUPPORTED_OUTPUT_FORMATS:
        raise ValueError(f"不支持的輸出格式:{output_format}")
    return "jpg" if output_format == "jpeg" else output_format


def get_output_suffix(output_format):
    return ".jpg" if output_format in ("jpg", "jpeg") else f".{output_format}"


def prepare_image_for_jpg(img, background_color=(255, 255, 255)):
    if img.mode in ("RGBA", "LA"):
        background = Image.new("RGB", img.size, background_color)
        alpha = img.getchannel("A")
        background.paste(img, mask=alpha)
        return background

    if img.mode == "P":
        img = img.convert("RGBA")
        if "A" in img.getbands():
            background = Image.new("RGB", img.size, background_color)
            background.paste(img, mask=img.getchannel("A"))
            return background

    return img.convert("RGB")


def resize_keep_ratio(img, max_width=None, max_height=None):
    if not max_width and not max_height:
        return img

    width, height = img.size
    target_width = max_width or width
    target_height = max_height or height

    resized = img.copy()
    resized.thumbnail((target_width, target_height))
    return resized


def save_image(img, output_path, output_format, quality):
    if output_format == "jpg":
        img = prepare_image_for_jpg(img)
        img.save(output_path, "JPEG", quality=quality, optimize=True)
        return

    if output_format == "png":
        img.save(output_path, "PNG", optimize=True)
        return

    if output_format == "webp":
        img.save(output_path, "WEBP", quality=quality, method=6)
        return

    raise ValueError(f"不支持的輸出格式:{output_format}")


def convert_one_image(image_path, output_dir, output_format, quality, max_width, max_height):
    output_suffix = get_output_suffix(output_format)
    output_path = output_dir / f"{image_path.stem}{output_suffix}"

    with Image.open(image_path) as img:
        img = resize_keep_ratio(img, max_width=max_width, max_height=max_height)
        save_image(img, output_path, output_format, quality)

    return output_path


def batch_convert(input_dir, output_dir, output_format, quality=80, max_width=None, max_height=None):
    input_dir = Path(input_dir)
    output_dir = Path(output_dir)
    output_format = normalize_format(output_format)

    if not input_dir.exists():
        raise FileNotFoundError(f"輸入目錄不存在:{input_dir}")

    if not input_dir.is_dir():
        raise NotADirectoryError(f"輸入路徑不是目錄:{input_dir}")

    output_dir.mkdir(parents=True, exist_ok=True)

    total = 0
    success = 0
    failed = 0

    for image_path in input_dir.rglob("*"):
        if not image_path.is_file():
            continue

        if image_path.suffix.lower() not in SUPPORTED_EXTENSIONS:
            continue

        total += 1

        try:
            output_path = convert_one_image(
                image_path=image_path,
                output_dir=output_dir,
                output_format=output_format,
                quality=quality,
                max_width=max_width,
                max_height=max_height,
            )
            success += 1
            print(f"[成功] {image_path} -> {output_path}")
        except Exception as exc:
            failed += 1
            print(f"[失敗] {image_path},原因:{exc}")

    print("-" * 60)
    print(f"處理完成:總數(shù)={total},成功={success},失敗={failed}")


def parse_args():
    parser = argparse.ArgumentParser(description="Python Pillow 圖片批量格式轉換工具")
    parser.add_argument("-i", "--input", required=True, help="輸入圖片目錄")
    parser.add_argument("-o", "--output", required=True, help="輸出圖片目錄")
    parser.add_argument(
        "-f",
        "--format",
        default="jpg",
        choices=["jpg", "jpeg", "png", "webp"],
        help="輸出圖片格式,默認 jpg",
    )
    parser.add_argument(
        "-q",
        "--quality",
        type=int,
        default=80,
        help="圖片質量,主要用于 jpg 和 webp,默認 80",
    )
    parser.add_argument("--max-width", type=int, default=None, help="最大寬度,保持比例縮放")
    parser.add_argument("--max-height", type=int, default=None, help="最大高度,保持比例縮放")
    return parser.parse_args()


def main():
    args = parse_args()

    batch_convert(
        input_dir=args.input,
        output_dir=args.output,
        output_format=args.format,
        quality=args.quality,
        max_width=args.max_width,
        max_height=args.max_height,
    )


if __name__ == "__main__":
    main()

十、運行示例

input_images 目錄下的圖片批量轉換為 JPG:

python batch_image_converter.py -i input_images -o output_images -f jpg

轉換為 PNG:

python batch_image_converter.py -i input_images -o output_images -f png

轉換為 WEBP,并設置壓縮質量:

python batch_image_converter.py -i input_images -o output_images -f webp -q 75

批量壓縮 JPG:

python batch_image_converter.py -i input_images -o compressed_images -f jpg -q 60

批量調整尺寸,最大寬度和高度不超過 800:

python batch_image_converter.py -i input_images -o resized_images -f jpg --max-width 800 --max-height 800

批量轉換并壓縮:

python batch_image_converter.py -i input_images -o result_images -f jpg -q 70 --max-width 1200 --max-height 1200

十一、代碼設計說明

這個工具把功能拆成了幾個函數(shù):

  • normalize_format():統(tǒng)一處理輸出格式
  • prepare_image_for_jpg():解決透明 PNG 轉 JPG 的問題
  • resize_keep_ratio():保持比例調整尺寸
  • save_image():根據(jù)目標格式保存圖片
  • convert_one_image():處理單張圖片
  • batch_convert():批量處理整個目錄
  • parse_args():解析命令行參數(shù)

這種拆分方式比把所有邏輯寫在一個循環(huán)里更容易維護。后續(xù)要增加水印、重命名、跳過已存在文件等功能,也可以繼續(xù)擴展。

十二、GUI 簡單擴展思路

當前工具是命令行版本,適合腳本自動化和批處理。如果要做成圖形界面,可以使用 Tkinter、PyQt 或 PySide。

一個簡單 GUI 可以包含這些控件:

  • 輸入目錄選擇按鈕
  • 輸出目錄選擇按鈕
  • 輸出格式下拉框
  • 圖片質量滑塊
  • 最大寬度和最大高度輸入框
  • 開始轉換按鈕
  • 轉換日志顯示區(qū)域
  • 進度條

如果使用 Tkinter,基本結構可以這樣設計:

import tkinter as tk
from tkinter import filedialog, messagebox


def choose_input_dir():
    path = filedialog.askdirectory()
    input_var.set(path)


def choose_output_dir():
    path = filedialog.askdirectory()
    output_var.set(path)


def start_convert():
    input_dir = input_var.get()
    output_dir = output_var.get()
    output_format = format_var.get()

    if not input_dir or not output_dir:
        messagebox.showwarning("提示", "請選擇輸入目錄和輸出目錄")
        return

    # 這里可以調用前面的 batch_convert() 函數(shù)
    messagebox.showinfo("完成", f"開始轉換為 {output_format}")


root = tk.Tk()
root.title("圖片批量格式轉換工具")
root.geometry("500x260")

input_var = tk.StringVar()
output_var = tk.StringVar()
format_var = tk.StringVar(value="jpg")

tk.Label(root, text="輸入目錄").pack(anchor="w", padx=20, pady=5)
tk.Entry(root, textvariable=input_var, width=50).pack(anchor="w", padx=20)
tk.Button(root, text="選擇輸入目錄", command=choose_input_dir).pack(anchor="w", padx=20, pady=5)

tk.Label(root, text="輸出目錄").pack(anchor="w", padx=20, pady=5)
tk.Entry(root, textvariable=output_var, width=50).pack(anchor="w", padx=20)
tk.Button(root, text="選擇輸出目錄", command=choose_output_dir).pack(anchor="w", padx=20, pady=5)

tk.Label(root, text="輸出格式").pack(anchor="w", padx=20, pady=5)
tk.OptionMenu(root, format_var, "jpg", "png", "webp").pack(anchor="w", padx=20)

tk.Button(root, text="開始轉換", command=start_convert).pack(pady=15)

root.mainloop()

實際開發(fā)時,可以直接復用命令行版本中的 batch_convert() 函數(shù)。這樣核心處理邏輯不用重寫,只需要把 GUI 控件中的參數(shù)傳給函數(shù)即可。

如果圖片數(shù)量很多,GUI 中還需要注意一點:不要在主線程里直接執(zhí)行批量轉換,否則界面可能卡住??梢允褂?threading.Thread 把轉換任務放到子線程中執(zhí)行。

十三、常見問題

1. 為什么 PNG 轉 JPG 報錯

常見原因是 PNG 圖片包含透明通道,而 JPG 不支持透明通道。解決方式是先轉換為 RGB,或者先合成白色背景。

2. 為什么壓縮后圖片還是很大

可能原因包括:

  • 原圖尺寸太大
  • quality 設置過高
  • PNG 本身不適合用 Pillow 大幅壓縮
  • 圖片內(nèi)容復雜,壓縮空間有限

可以同時使用降低質量和調整尺寸兩種方式。

3. 為什么批量處理時有些圖片失敗

可能原因包括:

  • 文件擴展名是圖片,但文件內(nèi)容已經(jīng)損壞
  • 文件權限不足
  • 路徑中存在特殊權限問題
  • 輸出目錄不可寫

所以批量腳本中要使用 try except,避免一張圖片失敗導致整個任務中斷。

十四、總結

本文使用 Python + Pillow 實現(xiàn)了一個圖片批量格式轉換工具,覆蓋了圖像處理入門中非常常見的幾個需求:

  • 安裝 Pillow
  • JPG 轉 PNG
  • PNG 轉 JPG
  • 圖片壓縮
  • 圖片尺寸調整
  • 批量處理整個目錄
  • 命令行完整代碼案例
  • GUI 圖形界面擴展思路

這個案例非常適合作為 Python 圖像處理入門練習。掌握這些基礎之后,可以繼續(xù)擴展水印添加、圖片裁剪、縮略圖生成、圖片重命名、EXIF 信息讀取等功能,逐步做成一個更完整的圖片處理工具箱。

以上就是使用Python+Pillow開發(fā)一個圖片批量格式轉換工具的詳細內(nèi)容,更多關于Python Pillow圖片格式轉換工具的資料請關注腳本之家其它相關文章!

相關文章

最新評論

息烽县| 南召县| 盐津县| 宁陵县| 察隅县| 清徐县| 鹰潭市| 原平市| 揭东县| 漯河市| 万年县| 龙江县| 大厂| 多伦县| 囊谦县| 弥勒县| 云龙县| 上蔡县| 罗山县| 青龙| 仁寿县| 衡南县| 乌拉特后旗| 平邑县| 宁蒗| 洛南县| 龙南县| 商洛市| 鄂托克前旗| 沙田区| 博兴县| 楚雄市| 宝应县| 罗山县| 丁青县| 视频| 岳西县| 馆陶县| 新宁县| 淳化县| 兴安盟|