Python實例題:圖片批量處理工具

目錄

Python實例題

題目

問題描述

解題思路

關鍵代碼框架

難點分析

Python實例題

題目

圖片批量處理工具

問題描述

開發一個 Python 工具,實現以下功能:

  • 遍歷指定文件夾下的所有圖片文件(支持常見格式如 jpg、png、webp)
  • 對每張圖片執行以下處理流程:
    • 尺寸縮放(按比例或固定尺寸)
    • 添加水印(文字或圖片水印)
    • 格式轉換(如將所有圖片轉為 png)
  • 使用多線程加速處理過程
  • 顯示處理進度和耗時統計
  • 支持錯誤處理(如損壞圖片跳過、權限問題提示)
  • 生成處理日志文件

解題思路

  • 使用ospathlib進行文件遍歷
  • 利用PIL(Pillow)庫進行圖像處理
  • 通過concurrent.futures.ThreadPoolExecutor實現多線程
  • tqdm庫顯示進度條
  • 設計日志系統記錄處理詳情
  • 采用面向對象設計封裝不同功能模塊

關鍵代碼框架

import os
import time
import logging
from PIL import Image, ImageDraw, ImageFont
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
from pathlib import Path# 配置日志系統
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',handlers=[logging.FileHandler("image_processor.log"),logging.StreamHandler()]
)class ImageProcessor:def __init__(self, source_dir, target_dir, max_workers=5):self.source_dir = Path(source_dir)self.target_dir = Path(target_dir)self.target_dir.mkdir(exist_ok=True, parents=True)self.max_workers = max_workersself.supported_formats = ['.jpg', '.jpeg', '.png', '.webp', '.bmp']self.processed_count = 0self.error_count = 0self.start_time = Nonedef get_image_files(self):"""獲取所有圖片文件路徑"""image_files = []for ext in self.supported_formats:image_files.extend(self.source_dir.glob(f"**/*{ext}"))return image_filesdef resize_image(self, img, target_size=(800, 600), keep_ratio=True):"""調整圖片尺寸"""if keep_ratio:img.thumbnail(target_size, Image.LANCZOS)else:img = img.resize(target_size, Image.LANCZOS)return imgdef add_text_watermark(self, img, text, position=(10, 10), font_size=16):"""添加文字水印"""draw = ImageDraw.Draw(img)font = ImageFont.truetype("simhei.ttf", font_size)  # 需要中文字體文件draw.text(position, text, fill=(255, 255, 255, 128), font=font)return imgdef add_image_watermark(self, img, watermark_path, opacity=0.5):"""添加圖片水印"""try:watermark = Image.open(watermark_path).convert("RGBA")watermark = watermark.resize((100, 100), Image.LANCZOS)img = img.convert("RGBA")# 水印位置(右下角)pos = (img.width - watermark.width - 10, img.height - watermark.height - 10)transparent = Image.new('RGBA', img.size, (0, 0, 0, 0))transparent.paste(img, (0, 0))transparent.paste(watermark, pos, watermark)# 調整透明度alpha = int(255 * opacity)watermark = watermark.copy()watermark.putalpha(alpha)transparent.paste(watermark, pos, watermark)return transparent.convert("RGB")except Exception as e:logging.warning(f"添加圖片水印失敗: {e}")return imgdef process_image(self, image_path):"""處理單張圖片"""try:# 構建目標文件路徑relative_path = image_path.relative_to(self.source_dir)target_path = self.target_dir / relative_pathtarget_path.parent.mkdir(exist_ok=True, parents=True)# 打開圖片img = Image.open(image_path)logging.info(f"處理圖片: {image_path}")# 執行處理流程img = self.resize_image(img, target_size=(1000, 800))img = self.add_text_watermark(img, "版權所有 ? 2025")img = self.add_image_watermark(img, "watermark.png")  # 需要存在水印圖片# 轉換格式并保存target_ext = ".png"  # 統一轉為png格式target_path = target_path.with_suffix(target_ext)img.save(target_path, quality=95)self.processed_count += 1return Trueexcept Exception as e:logging.error(f"處理圖片失敗 {image_path}: {e}")self.error_count += 1return Falsedef run(self):"""啟動批量處理"""self.start_time = time.time()image_files = self.get_image_files()logging.info(f"發現 {len(image_files)} 張圖片待處理")if not image_files:logging.warning("未找到可處理的圖片文件")return# 使用線程池處理with ThreadPoolExecutor(max_workers=self.max_workers) as executor:results = list(tqdm(executor.map(self.process_image, image_files),total=len(image_files),desc="處理進度",unit="圖片"))# 統計結果end_time = time.time()elapsed = end_time - self.start_timelogging.info(f"處理完成!共處理 {self.processed_count} 張圖片,"f"失敗 {self.error_count} 張,耗時 {elapsed:.2f} 秒")print(f"處理完成!總耗時: {elapsed:.2f} 秒")print(f"成功處理: {self.processed_count} 張,失敗: {self.error_count} 張")# 使用示例
if __name__ == "__main__":processor = ImageProcessor(source_dir="input_images",target_dir="output_images",max_workers=8)processor.run()

難點分析

  • 多線程同步問題:需要確保processed_count等共享變量的線程安全
  • 中文字體支持:添加中文水印時需要指定正確的字體文件路徑
  • 內存管理:大尺寸圖片處理時可能導致內存溢出,需配合Image.LOAD_TRUNCATED_IMAGES等參數
  • 異常處理:需要處理文件權限、圖片損壞、格式不支持等多種異常情況
  • 性能優化:可通過調整線程數、使用生成器分批處理大文件等方式優化

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85319.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85319.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85319.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

超圖superMap iObjects for Java的Jar使用中遇到的問題

一、 cannot open shared object file: No such file or directory 1. 問題 2. 解決方法 (1)檢查有沒有配置環境變量 PATH (2)創建軟連接 ln -s (3)將主機 /usr/lib64 目錄中的libgomp.so.1 復制到 /pla…

常見的藍牙5.0抗干擾技術和算法

常見的藍牙5.0抗干擾技術和算法: 跳頻擴頻(Frequency Hopping Spread Spectrum, FHSS) 通過在不同的頻率通道上快速切換數據傳輸,減少與固定頻率干擾源的沖突。 直接序列擴頻(Direct Sequence Spread Spectrum, DSSS&…

牛客與Moka深化合作,升級AI面試對接,引領招聘變革

近日,AI 招聘平臺牛客與國內領先的人力資源全模塊平臺 Moka 宣布完成 AI 面試產品的全新對接升級。此次升級實現了從 Moka 到牛客的一鍵互綁,并打通了簡歷出題、風險點提問、優勢技能挖掘等核心功能,為企業提供更加高效智能的面試體驗。 這一…

Vue 3 路由跳轉全面指南(Composition API + <script setup>)

一、前言:為什么要學習 Vue Router? 在單頁面應用(SPA)開發中,路由管理是核心功能之一。Vue Router 作為 Vue.js 官方推薦的路由解決方案,與 Vue.js 深度集成,提供了以下重要功能: 頁面無刷新跳轉&#x…

JavaScript基礎-常用的鍵盤事件

一、前言 在網頁開發中,用戶交互 是非常重要的一環。除了鼠標操作之外,鍵盤事件也是前端開發中最常見的交互方式之一。 JavaScript 提供了多個用于監聽和處理鍵盤輸入的事件,例如 keydown、keyup 和 keypress。掌握這些事件可以幫助我們實現…

解決 Android 項目下載依賴缺失導致的問題

解決 Android 項目下載依賴缺失導致的問題 在項目根目錄下的 build.gradle 文件中增加下面的代碼: buildscript {repositories {...maven {url "https://maven.aliyun.com/repository/jcenter"}maven {url "https://maven.aliyun.com/repository/c…

Clang Code Model: Error: The clangbackend executable “D:\Soft\Qt5.12.12\Tool

Qt Creator->菜單->幫助->關于插件->C>去掉ClangCodeModel勾選->重啟Qt Creator 參考:【問題解決】Qt Creator 報錯:Clang Code Model: Error: The clangbackend executable_qt clang code model-CSDN博客

高頻面試之12 HBase

12 HBase 文章目錄 12 HBase12.1 HBase存儲結構12.2 HBase的寫流程12.3 HBase的讀流程12.6 HBase的合并12.7 RowKey設計原則12.8 RowKey如何設計12.9 HBase二級索引原理 12.1 HBase存儲結構 架構角色: 1)Master 實現類為HMaster,負責監控集群…

Vue3 + TypeScript + Element Plus 表格實例null檢查方法

代碼分析&#xff1a; // 表格實例對象 const tableRef ref<ElTableExtendedInstance | null>(null); // 表格列配置列表 const columnConfigs ref<IColumnConfig[]>([{ prop: "index", label: "序號", width: 60 },{ prop: "batchNo&…

Neo4j常見語法-unwind

unwind的用法&#xff08;UNWIND 是一個強大的操作符&#xff0c;用于將集合&#xff08;列表、數組&#xff09;展開為多行數據。它類似于關系型數據庫中的 UNNEST 或 LATERAL JOIN&#xff0c;是 Cypher 查詢中處理集合數據的核心工具&#xff09; &#xff08;1&#xff09;…

JavaEE-Spring-IoCDI

Spring是?個開源框架, 他讓我們的開發更加簡單. 他?持?泛的應?場 景, 有著活躍?龐?的社區, 這也是Spring能夠?久不衰的原因. 但是這個概念相對來說, 還是?較抽象. ??句更具體的話來概括Spring, 那就是: Spring 是包含了眾多?具?法的 IoC 容器 容器是?來容納…

CppCon 2017 學習:10 Core Guidelines You Need to Start Using Now

C.45: 不要定義一個僅僅初始化成員變量的默認構造函數&#xff0c;而是使用類內成員初始化器 如果你有一個默認構造函數&#xff0c;它的唯一作用是給成員變量賦默認值&#xff08;如 1、2、3&#xff09;&#xff0c;這更清晰、簡單的方法是直接在成員變量聲明時使用類內初始…

Java并發編程實戰 Day 28:虛擬線程與Project Loom

【Java并發編程實戰 Day 28】虛擬線程與Project Loom 文章內容 在“Java并發編程實戰”系列的第28天&#xff0c;我們將聚焦于**虛擬線程&#xff08;Virtual Threads&#xff09;**和 Project Loom&#xff0c;這是 Java 在高并發場景下的一次重大革新。隨著現代應用對性能和…

Linux系統移植⑦:uboot啟動流程詳解-board_init_r執行過程

Linux系統移植⑦&#xff1a;uboot啟動流程詳解-board_init_r執行過程 在uboot中&#xff0c;board_init_r 是啟動流程中的一個關鍵函數&#xff0c;負責完成板級&#xff08;board-specific&#xff09;的后期初始化工作。以下是關于該函數的詳細說明&#xff1a; 1. 函數作…

OpenStack入門體驗

1.1云計算概述 相信大家都聽到很多的阿里云、騰訊云、百度云等等這些詞,那到底什么是云計算?云 計算又能做什么? 1.1.1什么是云計算 云計算(cloud computing)是一種基于網絡的超級計算模式,基于用戶的不同需求,提供所需的資源,包括計算資源、存儲資源、網絡資源等。云計算…

RK 安卓10/11平臺 HDMI-IN 調試

這篇文章我們介紹一下在安卓9、10、11的版本上&#xff0c;rk平臺的hdmi-in功能是如何實現的&#xff0c;下篇文章我們再介紹安卓12之后的版本有了什么變化。希望對在rk平臺調試hdmi-in功能的朋友有一些幫助。 目錄 &#xff08;1&#xff09;概述 &#xff08;2&#xff09;…

MongoDB學習記錄(快速入門)

MongoDB核心 基礎概念 數據庫 數據庫是按照數據結構來組織、存儲和管理數據的倉庫。在內存中運行的&#xff0c;一旦程序運行結束或者計算機斷電&#xff0c;程序運行中的數據都會丟失。我們需要將一些程序運行的數據持久化到硬盤之中&#xff0c;以確保數據的安全性。數據庫…

阿里一面:微服務拆分需要考慮什么因素?

要拆分微服務&#xff0c;首先我們要了解微服務拆了會有什么問題&#xff1f;怎么合理拆服務&#xff1f; 拆分服務會帶來什么問題&#xff1f; 舉個電商系統下單扣庫存的例子。 對于單體應用&#xff0c;通訊在進程內部進行&#xff0c;下單方法調用扣庫存方法&#xff0c;…

3D高斯潑濺和4D高斯

1.高斯函數 想象你往平靜的湖水里扔一塊石頭&#xff0c;水波會以石頭落點為中心向外擴散&#xff0c;形成一個逐漸衰減的圓形波紋。高斯函數的形狀就和這個波紋類似&#xff1a; 中心最高&#xff08;石頭落點&#xff0c;波峰最強&#xff09;。越往外&#xff0c;高度&…

comfyui插件和comfyui mac安裝

mac comfyui安裝包 ComfyUI.zip&#xff0c;官方最新0.3.40&#xff0c;如果后續官方有迭代&#xff0c;可以直接通過git更新源碼升級 comfyui插件下載&#xff0c;解壓放到custom_nodes目錄下&#xff0c;包含 comfyui-animatediff-evolved&#xff08;視頻插件&#xff09; 和…