小編寫這篇文章的主要目的,主要是講解一些關于python的事情,比如需要對圖片進行批量壓縮,壓縮的方法還是比較的多的,那么,為了提高效率,怎么進行批量壓縮呢?下面就給大家詳細解答下。
前言
最近在研究怎么對圖片資源進行無損壓縮,網上也找了一些資料。總而言之,收獲不少,所以想對最近的學習做個總結。
無損壓縮其實是相對而言的,目的是為了減小圖片資源的內存大小但又不影響圖片的顯示質量。下面我將介紹兩種批量壓縮圖片的方法,方法一是使用python和Pillow模塊對圖片進行壓縮,這個方法對jpeg格式的圖片有非常高的壓縮效率,但該方法不太適合對png圖片進行壓縮。另一個方式是使用Python和Selenium模塊操縱Squoosh批量壓縮圖片。
使用Python和Pillow模塊壓縮圖片
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) 1、優化flag 開啟optimize設置,這是以CPU耗時為代價節省額外的文件大小,由于本質沒變,對圖片質量沒有絲毫影響。 ... if im.format=='JPEG': save_args['quality'].value=85 save_args['optimize']=True ...
2、漸進式JPEG
當我們將一張圖片保存為JPEG時,你可以從下面的選項中選擇不同的類型:
標準型:JPEG圖片自上而下載入。
漸進式:JPEG圖片從模糊到清晰載入。
漸進式的選項可以在Pillow中輕松的啟用(progressive=True)。漸進式文件的被打包時會有一個小幅的壓縮。
... if im.format=='JPEG': save_args['quality'].value=85 save_args['optimize']=True save_args['progressive=True']=True ...
3、JPEG動態質量
最廣為人知的減小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 ...
使用Python和Selenium模塊操縱Squoosh批量壓縮圖片
Squoosh是谷歌發布的一款開源的圖片在線壓縮服務(偽),雖然需要用瀏覽器打開,但其實是一個整合了許多命令行工具的前端界面,調用的是本地的計算資源,所以只要打開過Squoosh一次,之后都會秒開,并且離線使用。不過最大的缺點就是不可以批量處理,如果我們要處理大量的圖片資源,一張張地進行壓縮處理將會消耗大量的人力成本和時間成本,這明顯是不能接受的。我們要解決的問題就是寫一個腳本來模擬瀏覽器的操作,使我們的雙手得到解放。
Python調用Selenium
這是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
到此為止,這篇文章就給大家介紹到這里了,希望可以為各位讀者帶來一定的幫助。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/128239.html
摘要:這個網站非常良心,開放了免費的,取消了每張大小的限制,只限定每個月處理張圖片。 showImg(https://segmentfault.com/img/remote/1460000019115596?w=4272&h=2848); 本文原創并首發于公眾號【Python貓】,未經授權,請勿轉載。原文地址:https://mp.weixin.qq.com/s/5hpFDgjCpfb0O1...
摘要:復雜系統仿真的微博客虛假信息擴散模型研究面向影子分析的社交媒體競爭情報搜集面向人機協同的移動互聯網政務門戶探析經驗證。微博客的企業競爭情報搜集移動社交媒體用戶隱私保護對策研究注意這里的提示,原先的個文件沒有被再次抽取,只有個新文件被抽取。 showImg(https://segmentfault.com/img/bVbiU7y?w=1000&h=508); 本文為你展示,如何用Pyth...
摘要:歡迎常來為什么要學老師上課時候就說過傳統算法解決確定性問題,而機器學習解決非確定性問題。機器學習算法機器學習算法和普通算法還是有很大區別的。而自動駕駛等前言機器人,都使用了增強學習。學習資料在線課程入門機器學習經典算法與應用書籍機器學習實戰 文章圖片來源于 GitHub,網速不佳的朋友請點我看原文。 順便軟廣一下個人技術小站:godbmw.com。歡迎常來?(^?^*) 1. 為什么要...
閱讀 911·2023-01-14 11:38
閱讀 878·2023-01-14 11:04
閱讀 740·2023-01-14 10:48
閱讀 1983·2023-01-14 10:34
閱讀 942·2023-01-14 10:24
閱讀 819·2023-01-14 10:18
閱讀 499·2023-01-14 10:09
閱讀 572·2023-01-14 10:02