<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近在研究怎麼對圖片資源進行無失真壓縮,網上也找了一些資料。總而言之,收穫不少,所以想對最近的學習做個總結。
無失真壓縮其實是相對而言的,目的是為了減小圖片資源的記憶體大小但又不影響圖片的顯示質量。下面我將介紹兩種批次壓縮圖片的方法,方法一是使用python和Pillow模組對圖片進行壓縮,這個方法對jpeg格式的圖片有非常高的壓縮效率,但該方法不太適合對png圖片進行壓縮。另一個方式是使用Python和Selenium模組操縱Squoosh批次壓縮圖片。
Pillow是Python上一個功能非常強大的圖形處理庫,若本地還沒安裝,可以通過指令:pip install Pillow安裝。使用Pillow進行壓縮的策略大致總結為三個:1、優化flag,2、漸進式JPEG,3、JPEG動態質量。
我們先用Python寫一個簡單的儲存圖片的例子:
from PIL import Image from io import StringIO import dynamic_quality im = Image.open("photo.jpg") print(im.format,im.size,im.mode) new_photo = im.copy() new_photo.thumbnail(im.size,resample=Image.ANTIALIAS) save_args = {'format':im.format} if im.format=='JPEG': save_args['quality'].value=85 new_photo.save("copy_photo.jpg",**save_args)
開啟optimize設定,這是以CPU耗時為代價節省額外的檔案大小,由於本質沒變,對圖片質量沒有絲毫影響。
... if im.format=='JPEG': save_args['quality'].value=85 save_args['optimize']=True ...
當我們將一張圖片儲存為 JPEG 時,你可以從下面的選項中選擇不同的型別:
漸進式的選項可以在 Pillow 中輕鬆的啟用 (progressive=True
)。漸進式檔案的被打包時會有一個小幅的壓縮。
... if im.format=='JPEG': save_args['quality'].value=85 save_args['optimize']=True save_args['progressive=True']=True ...
最廣為人知的減小 JPEG 檔案大小的方法就是設定 quality
。很多應用儲存 JPEG 時都會設定一個特定的質量數值。
質量其實是個很抽象的概念。實際上,一張 JPEG 圖片的每個顏色通道都有不同的質量。質量等級從 0 到 100 在不同的顏色通道上都對應不同的量化表,同時也決定了有多少資訊會丟失。
在訊號域量化是 JPEG 編碼中失去資訊的第一個步驟。
我們可以動態地為每一張圖片設定最優的質量等級,在質量和檔案大小之間找到一個平衡點。我們有以下兩種方法可以做到這點:
Bottom-up: 這些演演算法是在 8x8 畫素塊級別上處理圖片來生成調優量化表的。它們會同時計算理論質量丟失量和和人眼視覺資訊丟失量。
Top-down: 這些演演算法是將一整張圖片和它原版進行對比,然後檢測出丟失了多少資訊。通過不斷地用不同的質量引數生成候選圖片,然後選擇丟失量最小的那一張。
我們選擇第二種方法:使用二分法在不同的質量等級下生成候選圖片,然後使用 pyssim 計算它的結構相似矩陣 (SSIM) 來評估每張候選圖片損失的質量,直到這個值達到非靜態可設定的閾值為止。這個方法讓我們可以有選擇地降低檔案大小(和檔案質量),但是隻適用於那些即使降低質量使用者也察覺不到的圖片。
下面是計算動態質量的程式碼dynamic_quality.py:
import PIL.Image from math import log from SSIM_PIL import compare_ssim def get_ssim_at_quality(photo, quality): """Return the ssim for this JPEG image saved at the specified quality""" ssim_photo = "tmp.jpg" # optimize is omitted here as it doesn't affect # quality but requires additional memory and cpu photo.save(ssim_photo, format="JPEG", quality=quality, progressive=True) ssim_score = compare_ssim(photo, PIL.Image.open(ssim_photo)) return ssim_score def _ssim_iteration_count(lo, hi): """Return the depth of the binary search tree for this range""" if lo >= hi: return 0 else: return int(log(hi - lo, 2)) + 1 def jpeg_dynamic_quality(original_photo): """Return an integer representing the quality that this JPEG image should be saved at to attain the quality threshold specified for this photo class. Args: original_photo - a prepared PIL JPEG image (only JPEG is supported) """ ssim_goal = 0.95 hi = 85 lo = 80 # working on a smaller size image doesn't give worse results but is faster # changing this value requires updating the calculated thresholds photo = original_photo.resize((400, 400)) # if not _should_use_dynamic_quality(): # default_ssim = get_ssim_at_quality(photo, hi) # return hi, default_ssim # 95 is the highest useful value for JPEG. Higher values cause different behavior # Used to establish the image's intrinsic ssim without encoder artifacts normalized_ssim = get_ssim_at_quality(photo, 95) selected_quality = selected_ssim = None # loop bisection. ssim function increases monotonically so this will converge for i in range(_ssim_iteration_count(lo, hi)): curr_quality = (lo + hi) // 2 curr_ssim = get_ssim_at_quality(photo, curr_quality) ssim_ratio = curr_ssim / normalized_ssim if ssim_ratio >= ssim_goal: # continue to check whether a lower quality level also exceeds the goal selected_quality = curr_quality selected_ssim = curr_ssim hi = curr_quality else: lo = curr_quality if selected_quality: return selected_quality, selected_ssim else: default_ssim = get_ssim_at_quality(photo, hi) return hi, default_ssim
然後在下面的程式碼中參照計算動態質量的方法:
... if im.format=='JPEG': save_args['quality'],value=dynamic_quality.jpeg_dynamic_quality(im) save_args['optimize']=True save_args['progressive']=True ...
Squoosh 是谷歌釋出的一款開源的圖片線上壓縮服務(偽),雖然需要用瀏覽器開啟,但其實是一個整合了許多命令列工具的前端介面,呼叫的是原生的計算資源,所以只要開啟過Squoosh一次,之後都會秒開,並且離線使用。不過最大的缺點就是不可以批次處理,如果我們要處理大量的圖片資源,一張張地進行壓縮處理將會消耗大量的人力成本和時間成本,這明顯是不能接受的。我們要解決的問題就是寫一個指令碼來模擬瀏覽器的操作,使我們的雙手得到解放。
這是 Squoosh 的主介面,Select an Image 其實是一個輸入框,那我們直接用 Selenium 把本地圖片的路徑輸入進去就行了:
輸入圖片路徑之後就會預設壓縮成 75% 質量的 MozJPEG,我覺得無論是壓縮比和質量都很不錯,所以就沒有改,等待頁面載入完成之後就直接下載:
我們可以認為出現 "..% smaller" 就算是壓縮完成,這時候直接點選右邊的下載按鈕即可。
程式碼:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import Select import os import re driver = webdriver.Chrome('C:/Users/admin/AppData/Local/Google/Chrome/Application/chromedriver.exe') # 列出目錄下所有的圖片,存在 images 這個列表中 images = os.listdir('C:/Users/admin/Pictures/Saved Pictures') # 處理所有圖片 for i in range(len(images)): # 構建圖片路徑 path = 'C:/Users/admin/Pictures/Saved Pictures/' + images[i] # 嘗試處理所有圖片 try: # 開啟 Squoosh driver.get('https://squoosh.app') # 找到輸入框 input_box = driver.find_element_by_xpath('.//input[@class="_2zg9i"]') # 輸入圖片路徑 input_box.send_keys(path) #設定圖片格式 select1 = Select(driver.find_elements_by_css_selector('select')[-1]) if re.match('.*.png',images[i]): select1.select_by_value("png") if re.match('.*.jpg',images[i]): select1.select_by_value("mozjpeg") # 等待出現 'smaller'字樣,10秒不出現則視為處理失敗 locator = (By.XPATH, './/span[@class="_1eNmr _1U8bE"][last()]') WebDriverWait(driver, 25).until(EC.text_to_be_present_in_element(locator, 'smaller')) # 找到下載按鈕 button = driver.find_elements_by_xpath('.//a[@title="Download"]')[-1] # 點選下載按鈕 button.click() # 輸出處理失敗的圖片路徑 except: print('*'*30) print('Error: '+ path +' failed!') print('*'*30) continue
到此這篇關於如何使用python對圖片進行批次壓縮的文章就介紹到這了,更多相關python圖片批次壓縮內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45