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

基于Python+OpenCV實現(xiàn)圖片批量縮放與加水印功能

 更新時間:2026年05月09日 09:45:07   作者:yuanpan  
本文通過使用OpenCV-python庫,介紹了如何批量處理圖片(縮放和添加水印),并提供了完整的Python代碼實現(xiàn),從圖片讀取與保存,圖片縮放,文字水印添加,中文路徑兼容處理,到整個文件夾批量處理,適合Python初學者學習圖像處理,需要的朋友可以參考下

在日常工作中,經(jīng)常會遇到這樣的圖片處理需求:

  • 商品圖片上傳前需要統(tǒng)一尺寸。
  • 活動照片需要批量壓縮后再發(fā)送。
  • 資料截圖需要加上公司名或項目名水印。
  • 文件夾里有幾十張、幾百張圖片,不適合一張張手工處理。

這些任務非常適合用 Python 自動化完成。本文使用 opencv-python 庫,帶你從圖片讀取、保存、縮放、添加文字水印開始,逐步完成一個“批量縮放并加水印”的完整小項目。

文章適合剛接觸圖像處理的 Python 初學者閱讀,不要求你提前掌握復雜的圖像算法。

1. OpenCV 是什么

OpenCV 是一個常用的計算機視覺和圖像處理庫,可以完成圖片讀取、圖片保存、尺寸變換、顏色處理、繪圖、視頻處理、人臉檢測、目標檢測等任務。

在 Python 中,我們通常安裝的是 opencv-python

pip install opencv-python

安裝完成后,可以在 Python 中導入:

import cv2

print(cv2.__version__)

如果能正常打印版本號,說明安裝成功。

2. 圖片讀取與保存

OpenCV 讀取圖片使用 cv2.imread(),保存圖片使用 cv2.imwrite()

import cv2

image = cv2.imread("input.jpg")

if image is None:
    raise FileNotFoundError("圖片讀取失敗,請檢查文件路徑")

cv2.imwrite("output.jpg", image)

需要注意的是,OpenCV 讀取到的圖片是一個 NumPy 數(shù)組。它的形狀通常是:

(高度, 寬度, 通道數(shù))

例如:

print(image.shape)

輸出可能是:

(1080, 1920, 3)

這表示圖片高度是 1080,寬度是 1920,通道數(shù)是 3。

3. 圖片縮放

圖片縮放使用 cv2.resize()

3.1 按指定寬高縮放

resized = cv2.resize(image, (800, 600))
cv2.imwrite("resized.jpg", resized)

注意:cv2.resize() 的尺寸參數(shù)順序是 (寬度, 高度),不是 (高度, 寬度)。

3.2 按比例縮放

如果希望圖片按 50% 縮?。?/p>

resized = cv2.resize(image, None, fx=0.5, fy=0.5)

其中:

  • fx 表示寬度縮放比例。
  • fy 表示高度縮放比例。

3.3 按目標寬度等比例縮放

實際項目中,更常見的是限制圖片寬度,同時保持原始寬高比:

height, width = image.shape[:2]
target_width = 1000
scale = target_width / width
target_height = int(height * scale)

resized = cv2.resize(image, (target_width, target_height))

這樣不會把圖片拉伸變形。

4. 添加文字水印

OpenCV 可以使用 cv2.putText() 在圖片上繪制文字。

watermarked = image.copy()

cv2.putText(
    watermarked,
    text="Python OpenCV",
    org=(30, 60),
    fontFace=cv2.FONT_HERSHEY_SIMPLEX,
    fontScale=1.2,
    color=(255, 255, 255),
    thickness=2,
    lineType=cv2.LINE_AA
)

cv2.imwrite("watermarked.jpg", watermarked)

參數(shù)說明:

  • text:水印文字。
  • org:文字左下角坐標,格式是 (x, y)。
  • fontFace:字體類型。
  • fontScale:字體大小。
  • color:文字顏色,OpenCV 使用 BGR 順序,不是 RGB。
  • thickness:文字粗細。
  • lineType:抗鋸齒方式,cv2.LINE_AA 會讓文字邊緣更平滑。

5. 半透明文字水印

直接把文字畫到圖片上會比較生硬。更常見的做法是使用一張透明圖層,再和原圖混合。

overlay = image.copy()
output = image.copy()

cv2.putText(
    overlay,
    "Python OpenCV",
    (30, 60),
    cv2.FONT_HERSHEY_SIMPLEX,
    1.2,
    (255, 255, 255),
    2,
    cv2.LINE_AA
)

alpha = 0.35
watermarked = cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0)

這里的 alpha 表示水印透明度。值越大,水印越明顯;值越小,水印越淡。

6. 批量處理整個文件夾圖片

批量處理的基本思路是:

  1. 遍歷輸入文件夾。
  2. 找到所有圖片文件。
  3. 讀取每張圖片。
  4. 縮放圖片。
  5. 添加水印。
  6. 保存到輸出文件夾。

常見圖片后綴包括:

IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}

遍歷文件夾可以使用 pathlib

from pathlib import Path

input_dir = Path("input_images")

for file_path in input_dir.iterdir():
    if file_path.suffix.lower() in IMAGE_EXTENSIONS:
        print(file_path)

7. 中文路徑兼容處理

很多初學者會遇到一個問題:圖片路徑里有中文時,cv2.imread() 可能讀取失敗,cv2.imwrite() 也可能保存失敗。

為了更穩(wěn)定地兼容中文路徑,可以使用 numpy.fromfile() + cv2.imdecode() 讀取圖片,用 cv2.imencode() + tofile() 保存圖片。

7.1 兼容中文路徑讀取

import cv2
import numpy as np


def imread_unicode(file_path):
    data = np.fromfile(str(file_path), dtype=np.uint8)
    image = cv2.imdecode(data, cv2.IMREAD_COLOR)
    return image

7.2 兼容中文路徑保存

def imwrite_unicode(file_path, image):
    ext = file_path.suffix
    success, encoded_image = cv2.imencode(ext, image)
    if not success:
        return False

    encoded_image.tofile(str(file_path))
    return True

這兩個函數(shù)在 Windows 中文目錄、中文文件名場景下非常實用。

8. 完整項目代碼

下面是完整可運行代碼。建議保存為 batch_resize_watermark.py。

項目目錄示例:

image_project/
├─ batch_resize_watermark.py
├─ input_images/
│  ├─ 示例圖片1.jpg
│  ├─ 示例圖片2.png
│  └─ 示例圖片3.webp
└─ output_images/

完整代碼:

from pathlib import Path

import cv2
import numpy as np


IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}


def imread_unicode(file_path: Path):
    """兼容中文路徑的圖片讀取。"""
    data = np.fromfile(str(file_path), dtype=np.uint8)
    image = cv2.imdecode(data, cv2.IMREAD_COLOR)
    return image


def imwrite_unicode(file_path: Path, image) -> bool:
    """兼容中文路徑的圖片保存。"""
    file_path.parent.mkdir(parents=True, exist_ok=True)

    ext = file_path.suffix
    success, encoded_image = cv2.imencode(ext, image)
    if not success:
        return False

    encoded_image.tofile(str(file_path))
    return True


def resize_keep_ratio(image, max_width: int = 1200):
    """按最大寬度等比例縮放圖片。"""
    height, width = image.shape[:2]

    if width <= max_width:
        return image.copy()

    scale = max_width / width
    target_height = int(height * scale)

    resized = cv2.resize(
        image,
        (max_width, target_height),
        interpolation=cv2.INTER_AREA
    )
    return resized


def add_text_watermark(
    image,
    text: str,
    alpha: float = 0.35,
    margin: int = 30
):
    """在圖片右下角添加半透明文字水印。"""
    output = image.copy()
    overlay = image.copy()

    height, width = image.shape[:2]

    font_face = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = max(width / 1200, 0.7)
    thickness = max(int(width / 600), 1)

    text_size, baseline = cv2.getTextSize(
        text,
        font_face,
        font_scale,
        thickness
    )
    text_width, text_height = text_size

    x = max(width - text_width - margin, margin)
    y = max(height - margin, text_height + margin)

    # 先畫一層深色陰影,提高淺色背景下的可讀性
    cv2.putText(
        overlay,
        text,
        (x + 2, y + 2),
        font_face,
        font_scale,
        (0, 0, 0),
        thickness + 1,
        cv2.LINE_AA
    )

    # 再畫白色文字
    cv2.putText(
        overlay,
        text,
        (x, y),
        font_face,
        font_scale,
        (255, 255, 255),
        thickness,
        cv2.LINE_AA
    )

    watermarked = cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0)
    return watermarked


def process_image(
    input_path: Path,
    output_path: Path,
    watermark_text: str,
    max_width: int
) -> bool:
    """處理單張圖片:讀取、縮放、加水印、保存。"""
    image = imread_unicode(input_path)
    if image is None:
        print(f"讀取失敗: {input_path}")
        return False

    resized = resize_keep_ratio(image, max_width=max_width)
    watermarked = add_text_watermark(resized, watermark_text)

    success = imwrite_unicode(output_path, watermarked)
    if not success:
        print(f"保存失敗: {output_path}")
        return False

    return True


def batch_process_images(
    input_dir: Path,
    output_dir: Path,
    watermark_text: str = "Python OpenCV",
    max_width: int = 1200
) -> None:
    """批量處理文件夾中的圖片。"""
    if not input_dir.exists():
        raise FileNotFoundError(f"輸入文件夾不存在: {input_dir}")

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

    image_files = [
        file_path
        for file_path in input_dir.iterdir()
        if file_path.is_file() and file_path.suffix.lower() in IMAGE_EXTENSIONS
    ]

    if not image_files:
        print(f"沒有找到可處理的圖片: {input_dir}")
        return

    success_count = 0

    for input_path in image_files:
        output_path = output_dir / input_path.name
        success = process_image(
            input_path=input_path,
            output_path=output_path,
            watermark_text=watermark_text,
            max_width=max_width
        )

        if success:
            success_count += 1
            print(f"處理完成: {input_path.name}")

    print(f"批量處理結(jié)束,成功 {success_count}/{len(image_files)} 張")
    print(f"輸出目錄: {output_dir.resolve()}")


def main():
    input_dir = Path("input_images")
    output_dir = Path("output_images")

    batch_process_images(
        input_dir=input_dir,
        output_dir=output_dir,
        watermark_text="Python OpenCV",
        max_width=1200
    )


if __name__ == "__main__":
    main()

運行腳本:

python batch_resize_watermark.py

如果運行成功,終端會輸出類似信息:

處理完成: 示例圖片1.jpg
處理完成: 示例圖片2.png
處理完成: 示例圖片3.webp
批量處理結(jié)束,成功 3/3 張
輸出目錄: D:\image_project\output_images

9. 效果演示說明

運行前,input_images 文件夾中存放原始圖片:

input_images/
├─ 風景照片.jpg
├─ 商品主圖.png
└─ 活動現(xiàn)場.webp

運行腳本后,output_images 文件夾會生成同名圖片:

output_images/
├─ 風景照片.jpg
├─ 商品主圖.png
└─ 活動現(xiàn)場.webp

處理后的圖片會有兩個變化:

  1. 如果原圖寬度超過 max_width,會被等比例縮放到指定最大寬度,例如 1200 像素。
  2. 圖片右下角會添加半透明文字水印,例如 Python OpenCV。

由于代碼使用了中文路徑兼容讀寫函數(shù),即使文件名是 風景照片.jpg、目錄名是 測試圖片,也可以正常讀取和保存。

10. 常見問題

10.1 為什么 OpenCV 的顏色是 BGR

OpenCV 默認使用 BGR 通道順序,而很多其他庫使用 RGB。比如白色在 OpenCV 中是:

(255, 255, 255)

紅色不是 (255, 0, 0),而是:

(0, 0, 255)

10.2 PNG 透明背景會保留嗎

本文代碼使用 cv2.IMREAD_COLOR 讀取圖片,會把圖片讀成三通道 BGR,透明通道不會保留。如果你需要保留透明背景,可以使用 cv2.IMREAD_UNCHANGED 讀取,并額外處理 alpha 通道。

10.3 水印位置如何調(diào)整

代碼中的水印位置由下面幾行控制:

x = max(width - text_width - margin, margin)
y = max(height - margin, text_height + margin)

這是右下角位置。如果想放到左上角,可以改成:

x = margin
y = text_height + margin

10.4 如何遞歸處理子文件夾

當前代碼只處理輸入目錄第一層圖片。如果要遞歸處理子文件夾,可以把:

input_dir.iterdir()

改成:

input_dir.rglob("*")

同時輸出路徑可以根據(jù)相對路徑生成,避免不同子目錄下的同名圖片互相覆蓋。

總結(jié)

本文完成了一個適合圖像處理初學者的 OpenCV 實戰(zhàn)項目:批量縮放文件夾圖片,并添加半透明文字水印。這個項目雖然不復雜,但覆蓋了圖片自動化處理中的幾個核心能力:

  • 使用 opencv-python 讀取和保存圖片。
  • 使用 cv2.resize() 等比例縮放圖片。
  • 使用 cv2.putText() 添加文字水印。
  • 使用 cv2.addWeighted() 實現(xiàn)半透明效果。
  • 使用 pathlib 批量遍歷文件夾。
  • 使用 imdecodeimencode 兼容中文路徑。

掌握這些基礎(chǔ)之后,你可以繼續(xù)擴展更多功能,例如圖片壓縮、格式轉(zhuǎn)換、添加 Logo 水印、遞歸處理子目錄、生成處理日志等,把它變成真正適合日常工作的圖片批處理工具。

以上就是基于Python+OpenCV實現(xiàn)圖片批量縮放與加水印功能的詳細內(nèi)容,更多關(guān)于Python OpenCV圖片批量縮放與加水印的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python matplotlib畫圖庫學習繪制常用的圖

    python matplotlib畫圖庫學習繪制常用的圖

    這篇文章主要為大家詳細介紹了python matplotlib畫圖庫學習繪制常用的圖,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Python?return函數(shù)返回值類型和幫助函數(shù)使用教程

    Python?return函數(shù)返回值類型和幫助函數(shù)使用教程

    這篇文章主要為大家介紹了Python?return函數(shù)返回值類型和幫助函數(shù)使用教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • python使用tkinter實現(xiàn)屏幕中間倒計時

    python使用tkinter實現(xiàn)屏幕中間倒計時

    這篇文章主要為大家詳細介紹了python使用tkinter實現(xiàn)屏幕中間倒計時,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 5道關(guān)于python基礎(chǔ) while循環(huán)練習題

    5道關(guān)于python基礎(chǔ) while循環(huán)練習題

    這篇文章主要給大家分享的是5道關(guān)于python基礎(chǔ) while循環(huán)練習題,無論學習什么語言,練習都是必不可少的,下面文章的練習題挺精湛的,需要的朋友可以參考一下
    2021-11-11
  • Python讀寫文件模式和文件對象方法實例詳解

    Python讀寫文件模式和文件對象方法實例詳解

    這篇文章主要介紹了Python讀寫文件模式和文件對象方法,結(jié)合實例形式詳細分析了Python文件操作常用技巧與相關(guān)注意事項,需要的朋友可以參考下
    2019-09-09
  • Python爬取微信小程序通用方法代碼實例詳解

    Python爬取微信小程序通用方法代碼實例詳解

    這篇文章主要介紹了Python爬取微信小程序通用方法代碼實例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • 深入了解python中的常見錯誤類型與解決

    深入了解python中的常見錯誤類型與解決

    在Python編程過程中,經(jīng)常會遇到各種錯誤,了解這些錯誤的類型以及如何處理它們是成為一位優(yōu)秀的Python開發(fā)者所必備的技能之一,下面就跟隨小編一起學習一下python中的常見錯誤類型吧
    2023-11-11
  • PyCharm:method may be static問題及解決

    PyCharm:method may be static問題及解決

    這篇文章主要介紹了PyCharm:method may be static問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Python pyinstaller庫的安裝配置教程分享

    Python pyinstaller庫的安裝配置教程分享

    pyinstaller模塊主要用于python代碼打包成exe程序直接使用,這樣在其它電腦上即使沒有python環(huán)境也是可以運行的。本文就來和大家分享一下pyinstaller庫的安裝配置教程,希望對大家有所幫助
    2023-04-04
  • 一文帶你搞懂Python中的數(shù)據(jù)容器

    一文帶你搞懂Python中的數(shù)據(jù)容器

    這篇文章主要為大家詳細介紹了Python中數(shù)據(jù)容器的相關(guān)資料,文中的示例代碼講解詳細,對我們學習Python有一定的幫助,感興趣的可以了解一下
    2022-11-11

最新評論

资中县| 阆中市| 祁连县| 伽师县| 松溪县| 荔浦县| 共和县| 西乌| 弋阳县| 石棉县| 富民县| 巴楚县| 景宁| 灵丘县| 乳源| 梁平县| 遂宁市| 自治县| 平安县| 南郑县| 八宿县| 崇州市| 汕尾市| 三门峡市| 自贡市| 高安市| 额济纳旗| 教育| 芒康县| 信丰县| 天津市| 龙里县| 温州市| 五峰| 宁都县| 和田市| 邹城市| 车险| 德庆县| 斗六市| 莆田市|