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

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

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

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

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

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

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

1. OpenCV 是什么

OpenCV 是一個(gè)常用的計(jì)算機(jī)視覺(jué)和圖像處理庫(kù),可以完成圖片讀取、圖片保存、尺寸變換、顏色處理、繪圖、視頻處理、人臉檢測(cè)、目標(biāo)檢測(cè)等任務(wù)。

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

pip install opencv-python

安裝完成后,可以在 Python 中導(dǎo)入:

import cv2

print(cv2.__version__)

如果能正常打印版本號(hào),說(shuō)明安裝成功。

2. 圖片讀取與保存

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

import cv2

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

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

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

需要注意的是,OpenCV 讀取到的圖片是一個(gè) 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 按目標(biāo)寬度等比例縮放

實(shí)際項(xiàng)目中,更常見(jiàn)的是限制圖片寬度,同時(shí)保持原始寬高比:

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))

這樣不會(huì)把圖片拉伸變形。

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ù)說(shuō)明:

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

5. 半透明文字水印

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

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. 批量處理整個(gè)文件夾圖片

批量處理的基本思路是:

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

常見(jiàn)圖片后綴包括:

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. 中文路徑兼容處理

很多初學(xué)者會(huì)遇到一個(gè)問(wèn)題:圖片路徑里有中文時(shí),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

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

8. 完整項(xiàng)目代碼

下面是完整可運(yùn)行代碼。建議保存為 batch_resize_watermark.py。

項(xiàng)目目錄示例:

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)

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

    # 再畫(huà)白色文字
    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"沒(méi)有找到可處理的圖片: {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()

運(yùn)行腳本:

python batch_resize_watermark.py

如果運(yùn)行成功,終端會(huì)輸出類(lèi)似信息:

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

9. 效果演示說(shuō)明

運(yùn)行前,input_images 文件夾中存放原始圖片:

input_images/
├─ 風(fēng)景照片.jpg
├─ 商品主圖.png
└─ 活動(dòng)現(xiàn)場(chǎng).webp

運(yùn)行腳本后,output_images 文件夾會(huì)生成同名圖片:

output_images/
├─ 風(fēng)景照片.jpg
├─ 商品主圖.png
└─ 活動(dòng)現(xiàn)場(chǎng).webp

處理后的圖片會(huì)有兩個(gè)變化:

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

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

10. 常見(jiàn)問(wèn)題

10.1 為什么 OpenCV 的顏色是 BGR

OpenCV 默認(rèn)使用 BGR 通道順序,而很多其他庫(kù)使用 RGB。比如白色在 OpenCV 中是:

(255, 255, 255)

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

(0, 0, 255)

10.2 PNG 透明背景會(huì)保留嗎

本文代碼使用 cv2.IMREAD_COLOR 讀取圖片,會(huì)把圖片讀成三通道 BGR,透明通道不會(huì)保留。如果你需要保留透明背景,可以使用 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 如何遞歸處理子文件夾

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

input_dir.iterdir()

改成:

input_dir.rglob("*")

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

總結(jié)

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

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

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

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

相關(guān)文章

  • python matplotlib畫(huà)圖庫(kù)學(xué)習(xí)繪制常用的圖

    python matplotlib畫(huà)圖庫(kù)學(xué)習(xí)繪制常用的圖

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

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

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

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

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

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

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

    Python讀寫(xiě)文件模式和文件對(duì)象方法實(shí)例詳解

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

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

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

    深入了解python中的常見(jiàn)錯(cuò)誤類(lèi)型與解決

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

    PyCharm:method may be static問(wèn)題及解決

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

    Python pyinstaller庫(kù)的安裝配置教程分享

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

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

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

最新評(píng)論

天峻县| 佛学| 府谷县| 巨鹿县| 将乐县| 云安县| 西乡县| 伊宁市| 凌海市| 玉龙| 康平县| 义乌市| 韶山市| 鄂州市| 江西省| 宝清县| 古田县| 巴彦淖尔市| 嘉峪关市| 吴川市| 鸡西市| 绿春县| 喀喇沁旗| 锦州市| 当雄县| 岑巩县| 海盐县| 酉阳| 武定县| 商都县| 贡嘎县| 太和县| 武安市| 横峰县| 安平县| 昌邑市| 毕节市| 思南县| 昌平区| 屯昌县| 霍城县|