python批量壓縮圖像的完整步驟
背景
今天在工作中,同事遇到一個上傳圖片的問題:系統要求的圖片大小不能超過512KB。但是同事又有很多照片。這要是每一個照片都用ps壓縮的話,那豈不是很崩潰。於是我寫瞭一個腳本,可以批量壓縮圖片到指定大小。直接造福同事、提高同事的工作效率。
解決方案
其實也不用賣關子瞭,就是使用python的pillow包就可以對圖片進行壓縮,如果一個圖片已經壓縮到指定大小瞭,那就停止壓縮,如果沒有達到指定大小,那就對壓縮後的圖片再進行壓縮,直到壓縮到自定范圍內。
可是為什麼不在網上找代碼呢?我也是找過,但是發現很多代碼質量參差不齊,都達不到我想要的效果,而且很不優雅。於是我隨手就寫瞭一個代碼,不僅僅代碼寫的簡單,而且邏輯清楚,最後為瞭效率,我還做瞭一個並行,同時使用10個進程處理。說實話,那可是真的飛快。
操作步驟
要求
- 默認是使用的是Anaconda的環境。
- 將所有要壓縮的圖片都放在一個文件夾下,然後每個圖片的格式隻能是下面三種:png,jpg, jpeg。如果是PNG也不行。因為PNG是png的大寫。
- 代碼中設置的圖像的壓縮後的大小是512KB,那麼你可以設置代碼中的target_size為500,隻要比512KB小就行瞭。
- 然後把我的代碼從GitHub上下載下來。代碼鏈接為:https://github.com/yuanzhoulvpi2017/tiny_python/blob/main/image_compression/ic.py
步驟
我這裡把所有圖片都放在瞭一個文件夾裡面,文件夾名稱為歷史截圖。然後我的這個歷史截圖和ic.py代碼都放在瞭little_code文件夾中。
在little_code文件夾下,打開終端。
直接運行的腳本:
python ic.py xxx_文件夾
等待一會,就會將整個文件夾下的所有圖片都轉化好瞭。
完整代碼:
如果上不去GitHub的話,我直接把代碼放在這裡,保存為一個python文件即可。比如保存的文件名為:ic.py
from PIL import Image from glob import glob import os from tqdm import tqdm import shutil import sys from itertools import chain from multiprocessing import Pool # image_dir = "image_dir" template_dir = 'template' output_dir = 'output' error_dir = 'error' def clean_dir(dir_name): if os.path.exists(dir_name): shutil.rmtree(dir_name) os.makedirs(dir_name) else: os.makedirs(dir_name) # image_file_list = glob(f"{image_dir}/*") # image_file_list def imagesize(filepath): """ 獲得文件的磁盤大小 :param filepath: :return: """ return os.path.getsize(filepath) / 1024 def compress_image(image_path): raw_image = Image.open(image_path) temp_image_name = image_path.split(os.sep)[-1] template_image = os.path.join(template_dir, temp_image_name) output_image = os.path.join(output_dir, temp_image_name) error_image = os.path.join(error_dir, temp_image_name) target_size = 500 # kb try: if imagesize(image_path) < target_size: shutil.copyfile(image_path, output_image) else: width, height = raw_image.size raw_image.resize((int(width * 0.9), int(height * 0.9)), Image.ANTIALIAS).save(template_image) while imagesize(template_image) > target_size: template_iamge2 = Image.open(template_image) width_2, height_2 = template_iamge2.size template_iamge2.resize((int(width_2 * 0.9), int(height_2 * 0.9)), Image.ANTIALIAS).save(template_image) shutil.copyfile(template_image, output_image) except Exception as e: shutil.copyfile(image_path, error_image) print(f'文件保存失敗: {image_path}') # print(e) if __name__ == '__main__': # 批量創建文件夾 [clean_dir(i) for i in [template_dir, output_dir, error_dir]] image_dir = sys.argv[1] image_file_list = list(chain(*[glob(os.path.join(image_dir, i)) for i in ['*.png', '*.jpg', '*.jpeg']])) # for temp_image_path in tqdm(image_file_list): # compress_image(temp_image_path) print(f'\n\n文件保存父目錄: {os.getcwd()}\n' f'輸出文件位置:{os.path.join(os.getcwd(), output_dir)}\n\n') # parallel P = Pool(processes=10) pbar = tqdm(total=len(image_file_list)) res_temp = [P.apply_async(func=compress_image, args=(i,), callback=lambda _: pbar.update(1)) for i in image_file_list] _ = [res.get() for res in res_temp]
附:批量將圖片的大小設置為指定大小
import os from PIL import Image # 源目錄 project_dir = os.path.dirname(os.path.abspath(__file__)) input = os.path.join(project_dir, 'src') # 輸出目錄 output = os.path.join(project_dir, 'dest') def modify(): # 切換目錄 os.chdir(input) # 遍歷目錄下所有的文件 for image_name in os.listdir(os.getcwd()): print(image_name) im = Image.open(os.path.join(input, image_name)) im.thumbnail((128, 128)) im.save(os.path.join(output, image_name)) if __name__ == '__main__': modify()
寫在後面
這個代碼說起來難,說起來也不難,如果認真看我歷史的文章的話,上面代碼中遇到的知識點都就會瞭。像是所謂的圖像壓縮、並行處理之類的,其實並不難。
到此這篇關於python批量壓縮圖像的文章就介紹到這瞭,更多相關python批量壓縮圖像內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python實現PDF轉換文本詳解
- 用python刪除文件夾中的重復圖片(圖片去重)
- 十個Python自動化常用操作,即拿即用
- python批處理將圖片進行放大實例代碼
- python 批量重命名移動文件