欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用python對(duì)圖片進(jìn)行批量壓縮詳解

 更新時(shí)間:2022年07月07日 11:17:30   作者:會(huì)編程的貓  
對(duì)于圖片強(qiáng)行被定義高和寬會(huì)變形,我們希望圖片被改變大小后,比例保持不變,完成對(duì)圖片的壓縮,下面這篇文章主要給大家介紹了關(guān)于如何使用python對(duì)圖片進(jìn)行批量壓縮的相關(guān)資料,需要的朋友可以參考下

前言

最近在研究怎么對(duì)圖片資源進(jìn)行無損壓縮,網(wǎng)上也找了一些資料??偠灾斋@不少,所以想對(duì)最近的學(xué)習(xí)做個(gè)總結(jié)。

無損壓縮其實(shí)是相對(duì)而言的,目的是為了減小圖片資源的內(nèi)存大小但又不影響圖片的顯示質(zhì)量。下面我將介紹兩種批量壓縮圖片的方法,方法一是使用python和Pillow模塊對(duì)圖片進(jìn)行壓縮,這個(gè)方法對(duì)jpeg格式的圖片有非常高的壓縮效率,但該方法不太適合對(duì)png圖片進(jìn)行壓縮。另一個(gè)方式是使用Python和Selenium模塊操縱Squoosh批量壓縮圖片。

使用Python和Pillow模塊壓縮圖片

Pillow是Python上一個(gè)功能非常強(qiáng)大的圖形處理庫,若本地還沒安裝,可以通過指令:pip install Pillow安裝。使用Pillow進(jìn)行壓縮的策略大致總結(jié)為三個(gè):1、優(yōu)化flag,2、漸進(jìn)式JPEG,3、JPEG動(dòng)態(tài)質(zhì)量。

我們先用Python寫一個(gè)簡(jiǎn)單的保存圖片的例子:

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、優(yōu)化flag

開啟optimize設(shè)置,這是以CPU耗時(shí)為代價(jià)節(jié)省額外的文件大小,由于本質(zhì)沒變,對(duì)圖片質(zhì)量沒有絲毫影響。

...
if im.format=='JPEG':
    save_args['quality'].value=85
    save_args['optimize']=True
...

2、漸進(jìn)式JPEG

當(dāng)我們將一張圖片保存為 JPEG 時(shí),你可以從下面的選項(xiàng)中選擇不同的類型:

  • 標(biāo)準(zhǔn)型: JPEG 圖片自上而下載入。
  • 漸進(jìn)式: JPEG 圖片從模糊到清晰載入。

漸進(jìn)式的選項(xiàng)可以在 Pillow 中輕松的啟用 (progressive=True)。漸進(jìn)式文件的被打包時(shí)會(huì)有一個(gè)小幅的壓縮。

...
if im.format=='JPEG':
    save_args['quality'].value=85
    save_args['optimize']=True
    save_args['progressive=True']=True
...

3、JPEG動(dòng)態(tài)質(zhì)量

最廣為人知的減小 JPEG 文件大小的方法就是設(shè)置 quality。很多應(yīng)用保存 JPEG 時(shí)都會(huì)設(shè)置一個(gè)特定的質(zhì)量數(shù)值。

質(zhì)量其實(shí)是個(gè)很抽象的概念。實(shí)際上,一張 JPEG 圖片的每個(gè)顏色通道都有不同的質(zhì)量。質(zhì)量等級(jí)從 0 到 100 在不同的顏色通道上都對(duì)應(yīng)不同的量化表,同時(shí)也決定了有多少信息會(huì)丟失。

在信號(hào)域量化是 JPEG 編碼中失去信息的第一個(gè)步驟。

我們可以動(dòng)態(tài)地為每一張圖片設(shè)置最優(yōu)的質(zhì)量等級(jí),在質(zhì)量和文件大小之間找到一個(gè)平衡點(diǎn)。我們有以下兩種方法可以做到這點(diǎn):

Bottom-up: 這些算法是在 8x8 像素塊級(jí)別上處理圖片來生成調(diào)優(yōu)量化表的。它們會(huì)同時(shí)計(jì)算理論質(zhì)量丟失量和和人眼視覺信息丟失量。

Top-down: 這些算法是將一整張圖片和它原版進(jìn)行對(duì)比,然后檢測(cè)出丟失了多少信息。通過不斷地用不同的質(zhì)量參數(shù)生成候選圖片,然后選擇丟失量最小的那一張。

我們選擇第二種方法:使用二分法在不同的質(zhì)量等級(jí)下生成候選圖片,然后使用 pyssim 計(jì)算它的結(jié)構(gòu)相似矩陣 (SSIM) 來評(píng)估每張候選圖片損失的質(zhì)量,直到這個(gè)值達(dá)到非靜態(tài)可配置的閾值為止。這個(gè)方法讓我們可以有選擇地降低文件大小(和文件質(zhì)量),但是只適用于那些即使降低質(zhì)量用戶也察覺不到的圖片。

下面是計(jì)算動(dòng)態(tài)質(zhì)量的代碼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

然后在下面的代碼中引用計(jì)算動(dòng)態(tài)質(zhì)量的方法:

...
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 是谷歌發(fā)布的一款開源的圖片在線壓縮服務(wù)(偽),雖然需要用瀏覽器打開,但其實(shí)是一個(gè)整合了許多命令行工具的前端界面,調(diào)用的是本地的計(jì)算資源,所以只要打開過Squoosh一次,之后都會(huì)秒開,并且離線使用。不過最大的缺點(diǎn)就是不可以批量處理,如果我們要處理大量的圖片資源,一張張地進(jìn)行壓縮處理將會(huì)消耗大量的人力成本和時(shí)間成本,這明顯是不能接受的。我們要解決的問題就是寫一個(gè)腳本來模擬瀏覽器的操作,使我們的雙手得到解放。

Python 調(diào)用 Selenium

這是 Squoosh 的主界面,Select an Image 其實(shí)是一個(gè)輸入框,那我們直接用 Selenium 把本地圖片的路徑輸入進(jìn)去就行了:

輸入圖片路徑之后就會(huì)默認(rèn)壓縮成 75% 質(zhì)量的 MozJPEG,我覺得無論是壓縮比和質(zhì)量都很不錯(cuò),所以就沒有改,等待頁面加載完成之后就直接下載:

我們可以認(rèn)為出現(xiàn) "..% smaller" 就算是壓縮完成,這時(shí)候直接點(diǎn)擊右邊的下載按鈕即可。

代碼:

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 這個(gè)列表中
images = os.listdir('C:/Users/admin/Pictures/Saved Pictures')
# 處理所有圖片
for i in range(len(images)):
    # 構(gòu)建圖片路徑
    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)
        #設(shè)置圖片格式
        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")

        # 等待出現(xiàn) 'smaller'字樣,10秒不出現(xiàn)則視為處理失敗
        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]
        # 點(diǎn)擊下載按鈕
        button.click()
    # 輸出處理失敗的圖片路徑
    except:
        print('*'*30)
        print('Error: '+ path +' failed!')
        print('*'*30)
        continue

總結(jié) 

到此這篇關(guān)于如何使用python對(duì)圖片進(jìn)行批量壓縮的文章就介紹到這了,更多相關(guān)python圖片批量壓縮內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python調(diào)用高德API實(shí)現(xiàn)批量地址轉(zhuǎn)經(jīng)緯度并寫入表格的功能

    Python調(diào)用高德API實(shí)現(xiàn)批量地址轉(zhuǎn)經(jīng)緯度并寫入表格的功能

    這篇文章主要介紹了Python調(diào)用高德API實(shí)現(xiàn)批量地址轉(zhuǎn)經(jīng)緯度并寫入表格的功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • python實(shí)現(xiàn)四人制撲克牌游戲

    python實(shí)現(xiàn)四人制撲克牌游戲

    這篇文章主要介紹了python實(shí)現(xiàn)四人制撲克牌游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Ubuntu下Python2與Python3的共存問題

    Ubuntu下Python2與Python3的共存問題

    Linux系統(tǒng)一般自帶Python,有時(shí)候又自己下載了Python,因此有可能Python2和Python3同時(shí)存在。那么當(dāng)我們?cè)赥erminal鍵入python的時(shí)候,會(huì)調(diào)出哪個(gè)Python呢?本文即解決這個(gè)問題
    2018-10-10
  • Python 元組(Tuple)操作詳解

    Python 元組(Tuple)操作詳解

    Python的元組與列表類似,不同之處在于元組的元素不能修改,元組使用小括號(hào),列表使用方括號(hào),元組創(chuàng)建很簡(jiǎn)單,只需要在括號(hào)中添加元素,并使用逗號(hào)隔開即可
    2014-03-03
  • Centos安裝Python虛擬環(huán)境及配置方法

    Centos安裝Python虛擬環(huán)境及配置方法

    這篇文章主要介紹了Centos安裝Python虛擬環(huán)境及配置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Django框架靜態(tài)文件處理、中間件、上傳文件操作實(shí)例詳解

    Django框架靜態(tài)文件處理、中間件、上傳文件操作實(shí)例詳解

    這篇文章主要介紹了Django框架靜態(tài)文件處理、中間件、上傳文件操作,結(jié)合實(shí)例形式詳細(xì)分析了Django框架中靜態(tài)文件處理、中間件及上傳文件操作相關(guān)實(shí)現(xiàn)技巧與注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • Django實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁彈出警告代碼

    Django實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁彈出警告代碼

    今天小編就為大家分享一篇Django實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁彈出警告代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Python聚類算法之DBSACN實(shí)例分析

    Python聚類算法之DBSACN實(shí)例分析

    這篇文章主要介紹了Python聚類算法之DBSACN,結(jié)合實(shí)例形式詳細(xì)分析了DBSACN算法的原理與具體實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • python實(shí)現(xiàn)圖書管理系統(tǒng)

    python實(shí)現(xiàn)圖書管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • PyTorch中的squeeze()和unsqueeze()解析與應(yīng)用案例

    PyTorch中的squeeze()和unsqueeze()解析與應(yīng)用案例

    這篇文章主要介紹了PyTorch中的squeeze()和unsqueeze()解析與應(yīng)用案例,文章內(nèi)容介紹詳細(xì),需要的小伙伴可以參考一下,希望對(duì)你有所幫助
    2022-03-03

最新評(píng)論