Ⅰ ImageMagick命令行使用方法
ImageMagick 的命令行由下面這些元素構成:
一個, 或多個文件名.
零個, 一個, 或多個圖像設置項.
零個, 一個, 或多個圖像操作項.
零個, 一個, 或多個圖像序列操作項.
零個, 一個, 或多個圖像組.
零個, 或一個圖像輸出名(convert, composite, montage, compare, import, conjure).
ImageMagick 擴展了「輸入文件名」它原本的含義, 現在它包括了:
文件名通配符.
明確的圖片格式.
內置圖像或圖案.
標準的輸入輸出, 文件描述符.
選取圖片的某些幀.
選擇圖片部分區域.
縮放了的內嵌圖像.
裁切了的內嵌圖像.
文件名引用.
在 Unix shell 環境下, 有一些特殊的字元是作為通配符使用的, 如 * 和 ? . ImageMagick 在李橡枯各個平台上都支持文件名通配符. 假如你想把某目錄下的 1.jpg, 2.jpg, 3,jpg, 4.jpg 和 5.jpg 這些文件轉成一個 GIF 動畫, 那麼你可以使用這條命令方便地引用所有的 JPEG 文件:
圖像的數據, 都是以一種確定的格式存儲的, 比如常見的 JPEG, PNG, TIFF 等. ImageMagick 在讀取, 解析圖片之前, 必須要知道圖片的格式.
多數圖像格式, 在文件中都設有一些標識來表明它屬於哪種格式. 如果沒有, ImageMagick 會根據文件的擴展名來判斷. 如 image.jpg 會告訴 ImageMagick 這是一張 JPEG 格式的圖片. 某些情況下, ImageMagick 不知道圖片的格式, 那麼這時就需要手動指定了. 如, 我們有一張名為 image , 存儲了 RGB 三原色位深原始信息的圖片(未經過任何壓縮的點陣圖), ImageMagick 當然無法自己得知它是什麼格式的圖片, 所以, 這時就需要我們明確指定圖片格式.
ImageMagick 有許多內置的圖像和圖案, 要使用 checkerboard 中的圖案:
Unix 和 Windows 都支持通過管道來重定向輸入輸出. ImageMagick 支持從標準的輸入輸出流中讀寫圖像數據, 由依次使用一個虛文件名 ‑ 來實現. 下面的例子把 convert 的輸出通過管道重定向到了 display .
第二個用於確定圖像格式的 gif: 是可選的, 因為 GIF 這種格式有自己的標識, ImageMagick 認識它. convert 同樣能以這種方式接受標准輸入:
其它的一些管道, 你可以通過它們的文件描述符來訪問. 文件描述符0, 1, 2已經被預定義為標准輸入, 標准輸出, 錯誤輸出. 如果一個管道被如敬指定為文件描述符 N, 那麼你可以通過 fd:N 來使用它. 下一個例子展示了如何通過管道重定向, 把文件描述符3, 4的數據添加到文件描述符5中.
ImageMagick 6.4.9-3 中才添加了對文件描述符的支持.
對於 Python, 你可以通過調用 File 對象的 fileno() 方法來獲取文件描述符.
在需要的時候, 你也可以為文件描述符指定具體的圖像格式:
某些圖片格式可以包括有多個圖像幀. 你可以只獲取第一幀, 最後一幀, 或中間的某些幀. 為此, 你可以在文件名之後, 以方括哪洞號括起來的形式指定幀. 下面的例子中, 對於一個有多幀的 GIF 圖片, 我們只取其第一幀.
在 Unix shell 的環境下, 一般中括弧是會被轉義的, 所以, 我們需要使用單引號把文件名引起來. Windows 的命令行環境下不用單引號也可以, 但多寫一對單引號並不會有什麼問題. 另外, 對於單引號和雙引號的作用, 在 Unix 和 Windows 這兩個平台上, 常常是相反的, 所以, 如果你使用 Windows ,那麼請注意將我們例子中的單引號改為雙引號.
你也可以一次獲取多幀, 在方括弧中標出一個范圍即可, 如下面的例子, 我們獲取了前四幀的圖像:
最後, 你可以一次獲取非連接的多幀. 下面的命令以3,2,4的順序獲取圖像:
注意上面的最後兩個命令, 輸出被寫入了一個類型為 MNG 的文件當中. 因為 MNG 支持保存多幀圖像, 而如 JPG 之類的格式只是保存單幀的圖像. 在下面「圖像輸出名」一節我們還會介紹這方面的內容.
最原始的點陣圖圖像, 就是一個表示出各像素點顏色的序列, 它的文件中沒有任何的其它像寬, 高, 格式標識等附加信息. 對於這類原始的圖像數據, 在處理時我們必須明確指定圖像的寬和高, 或者給出一個范圍. 在下面的例子中, 我們要處理的圖片是一個8位的 RGB 點陣圖, 寬是 6000, 高為 4000, 而我們只需要獲取一塊中心附近 600×400 的圖像信息.
使用 ‑extract 選項也可以實現相同的功能:
讀入一些圖片的同時, 重新定義它們的尺寸是很方便的. 假設你有很多的大的 JPEG 圖片需要轉換成一組 PNG 格式的縮略圖:
這里, 所以的圖片都會被讀入並且分別被重定義大小. 在讀入的同時定義尺寸在效率上更好, 同時資源佔用也更少:
同上.
靠一個另外的文件名, 來表示實際要讀取的圖像文件名, 實現這個功能有兩種方法, 第一種方法是使用 @ 這個符號, 來指定一個文件, 這個文件中包含有實際需要讀取的圖像文件名, 如一個名為 myimages.txt 的文本文件中有如下內容:
下面的命令, ImageMagick 就會讀入 frame001.jpg, frame002.jpg, frame003.jpg .
另一種方法, 是在文件名中使用格式化字元串, 然後在後面的方括弧中指定一個范圍. 看下面的例子:
ImageMagick 實際上會去讀取如下的圖像:
命令行中的一個設置項, 可以作用於讀入的圖像, 圖像操作, 或者將會被輸出的圖像. 一個設置項被設置後會一直發揮作用除非它被重置或命令執行完畢. 圖像設置命令包括有:
下面例子中的 ‑channel 會被作用於每一個圖像, 就像我們說的那樣, 設置項會持續起作用.
圖像操作項與圖像設置項不同, 它只作用於緊接著存在的一個圖像, 僅僅是這一個圖像, 之後, 圖像操作項就會失效. 在這里, 我們說明一下. 命令行參數有三種, 前面講過的圖像設置項, 這里的圖像操作項, 以及後面會講到的序列操作項. 圖像操作項包括下面這些.
下面例子, ‑negate 這項只對 wand 有效, 對 wizard 是無效的(但是, 如果把它放在 wizard 後的話, 則會作用於這兩張圖).
一個圖像序列操作項, 只作用於緊接著存在的一個圖像序列, 它們是.
許多命令行選項都有一個 geometry 參數, 用於指定圖像的寬, 高等信息. 因為圖像的坐標系, 尺寸, 位置等信息是我們經常會用到的, 所以為了方便, geometry 這個參數可以用不同的格式給出. 關於這點, 接下來我們會詳細地介紹.
一些命令行選項可接受如下多種格式的 geometry 參數. 請記住, 它們處理具體參數時的效果是不同的, 詳細的內容可查閱它們各個的說明文檔.
geometry 參數可以使用下表列出的多種格式指定. 最常用的一種格式是 size[offset] , 意為 size 是必須給出的, 而 offset 則是可選的. 不過, 有時 [size]offset 也行. 同時要注意, geometry 這個參數中, 絕不允許出現空格符.
下面展示了一些簡單的例子, 用以說明如何給出 ‑resize 的 geometry 參數. 我們將使用內置的 logo: 這張圖作為我們的「輸入圖像」. logo: 這張原始圖片寬為640像素, 高480像素, 記為 640×480. 就像你看到的, 寬總在高的前面. 這條規則同樣適用於我們可能會講到的「坐標」或「偏移」.
看一些例子:
(@的作用前面已經提到過了)
請注意引號的使用. 上面的例子, 包括後面的例子中, 我們都使用引號把 geometry 引起來了的. 很多時候, 這樣做不是必須的, 但當你使用了 < 和 > 的時候, 就一定要使用引號, 否則這兩個符號會被當成命令行的重定向操作處理. 另外, 在 Windows 平台上, ^ 也必須使用引號. 所以, 為了安全起見, 我們最好養成對於 geometry 總是使用引號的習慣.
我們通過一些例子來說明 geometry 參數中的 offsets. 使用它的一個典型情形是在 ‑region 這個選項中. ‑region 跟在一些其它的命令後, 用於指定一塊矩形區域. 所以, 你除了需要指定這個矩形區域的寬和高, 還需要指定它的一個起始點(左上角的點). 下面的第一個例子中, 我們指定了一個 100×200 的區域, 位置在 x=10, y=20, 或者我們應該寫成 (x,y) = (10,20).
注意, offsets 必須帶上 +/‑. 它表示的是一個相對偏移, 而不是一個絕對坐標. offsets 的參照點不是固定的, 但默認情況下, 它是 (0,0), 即左上角, 上面的第一個例子就是這種情況.
offsets 有可能「出界」, 就像第二個例子中的那樣, -10+20, 對於這個有一部分出界的矩形執行 ‑negate, 實際的效果也就相當於 90×200+0+20.
第三個例子中, 一來就使用了 ‑gravity 選項, 它把當前坐標原點(或叫參照原點)設置為圖像的正中, 即 (320,240) 的位置, 因為這張圖的尺寸是 640×480. 這意味著後面的 offsets 的實際效果與前面兩例就有所不同, 變成了 (320-10, 240+20) = (310,260). 同時 100×200 也不再是根據左上角來計算, 而是根據中心點計算. 即以 (310,260) 為中心的一個 100×200 的矩形. 顯然, 它的左上角在 (310-50,260-100) = (260,160).
它讓你在一個隔離的組中處理一張圖像或一個圖像序列, 處理完後, 把結果返回到正常流程中. 圖像組用一對括弧標示, 裡面的所有操作只對當前組有效. 如下例, 我們限制 ‑rotate 操作只對 wizard.gif 有效:
特別注意, 在 Unix 平台下, 用於圖像組的括弧是需要使用 \ 轉義的, 因為小括弧在 shell 中有其它的特殊作用. 但是, Windows 平台下的小括弧不需要轉義. 另外, 在小括弧內的兩側, 都有一個空格, 請留意.
前面我們已經談到了一些命令行中的操作項, 不過, 下面這幾個操作項對於處理一個圖像組是比較常用的:
上面幾個操作項的參數, 都是一個索引值, 用以表示在圖像組中的某個圖像. 圖像組中的第一個圖像的索引值是 0. 同時, 這個索引值你也可以使用負數, -1 就是圖像組中的最後一個圖像.
ImageMagick 擴展了原來的「輸出文件名」的概念, 在 ImageMagick 中, 一個圖像輸出可以是:
一種明確的圖像格式.
輸出到系統的標准輸出.
文件名引用.
圖像信息都是以某種即定的格式存儲起來的, 這些格式包括我們熟悉的 JPEG, PNG, TIFF 等. ImageMagick 在寫出某個圖像時, 必須知道應該使用哪一種格式寫出. 通常情況下, ImageMagick 可以根據擴展名來判斷格式, 如, 對於 image.jpg ImageMagick 會以 JPEG 格式來寫出. 某些情況下沒有給出圖像的格式信息, 而你又沒有明確指定, 這時, ImageMagick 會以圖像原來的格式寫出. 比如, 我們希望把圖像存為名為 image 的原始 RGB 點陣圖:
Unix 支持通過管道在各個程序間重定向輸入輸出. ImageMagick 可以使用一個特殊的文件名 ‑ 來實現管道間的重定向操作. 下面的例子中, 我們把 convert 的輸出重定向到 display 中:
這里, 你不一定要明確指定圖像格式, GIF 這種格式有它自己的標示, ImageMagick 可以自動正確地識別出.
另外還有一種輸出方式, 是使用格式化字元串來輸出多個圖像. 假如我們把輸出圖像名寫成 image‑%d.jpg , 同時我們的圖像序列中有 3 個圖像, 那麼會得到如下的多個輸出結果:
還有一種情況, 假如你希望用圖像的某些屬性來作為其文件名的一部分, 那麼可以這樣:
其結果是:
Ⅱ png圖片怎麼通過代碼實現壓縮到指定的文件大小,比如5M壓縮到200KB,比如用pngquant或imageMagick
先用命令行形式進行 PNG 壓縮。
1,下載 windows安裝包 或者 mac 和 linux 版本的安裝包。
2,命令行輸入 pngquant 就可以使用了;
3,為了使用方便,可以配置環境變數(後面如果和 picom 集成在了一起再去掉 )。
快速使用 pngquant
pngquant 圖片名稱.png
對於一些可選參數的說明:
1,--skip-if-larger pngquant 有時候壓縮的文件會比源文件大。這個選項會判斷,如果大就取消執行。強烈建議加上
2,--quality 0-100 圖片質量。對於顏色沒有特別要求的可以縮減到 10, 但是越小壓縮率越低,通常不需要設置。
3,--force 強制執行,pngquant 會判斷,如果有一個已經壓縮的同名文件在當前文件夾,就不會執行。這個選項會覆蓋原來的文件。
4,--output file 指定輸入文件的名稱。 可以指定為 jpg 格式,但是圖片不會變得更小。
5,--speed 執行速度
使用 subprocess 調用 pngquant 命令行
對應的程序:
import subprocess
subprocess.run('pngquant elephant.png')
如果想獲取程序運行時屏幕上顯示的內容,可以使用 check_output 方法,在這里不需要。
接下來使用 subprocess 封裝對應的壓縮函數:
def pngquant_compress(fp, force=False, quality=None):
"""壓縮函數.
參數:
fp: 文件名稱
force: 如果存在同名文件,是否覆蓋
quality: 壓縮質量。 10-40, or 10
"""
force_command = '-f' if force else ''
quality_command = ''
if quality and isinstance(quality, int):
quality_command = f'--quality {quality}'
if quality and isinstance(quality, str):
quality_command = f'--quality {quality}'
command = f'pngquant {fp} --skip-if-larger {force_command} {quality_command}'
subprocess.run(command)
if __name__ == "__main__":
pngquant_compress('elephant.png