国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

圖像處理 - ImageMagick 簡單介紹與案例

youkede / 3565人閱讀

摘要:是一款創建編輯合成,轉換圖像的命令行工具。上面兩條三次貝塞爾曲線的坐標分別表示起始點,起始點的控制點,結束點的控制點,結束點。

在客戶端我們可以用 PhotoShopGUI 工具處理靜態圖片或者動態 GIF 圖片,不過在服務器端對于 WEB 應用程序要處理圖片格式轉換,縮放裁剪,翻轉扭曲,PDF解析等操作, GUI 軟件就很難下手了,所以此處需要召喚命令行工具來幫我們完成這些事。

ImageMagick: 是一款創建、編輯、合成,轉換圖像的命令行工具。支持格式超過 200 種,包括常見的 PNG, JPEG, GIF, HEIC, TIFF, DPX, EXR, WebP, Postscript, PDF, SVG 等。功能包括調整,翻轉,鏡像(mirror),旋轉,扭曲,修剪和變換圖像,調整圖像顏色,應用各種特殊效果,或繪制文本,線條,多邊形,橢圓和貝塞爾曲線等。

官網:https://www.imagemagick.org,下面放個小標識。

安裝 ImageMagick
支持 Linux, Windows, Mac OS X, iOS, Android OS 等平臺
https://www.imagemagick.org/s...

因為我是 MAC 機器,演示一下 brew 的安裝方式咯

brew install imagemagick
基本命令與格式 1、基本命令
ImageMagick 包括一組命令行工具來操作圖片,安裝好 ImageMagick 后,終端就可以使用如下命令了。

magick: 創建、編輯圖像,轉換圖像格式,以及調整圖像大小、模糊、裁切、除去雜點、抖動 ( dither )、繪圖、翻轉、合并、重新采樣等。
convert: 等同于 magick 命令。
identify: 輸出一個或多個圖像文件的格式和特征信息,如分辨率、大小、尺寸、色彩空間等。
mogrify: magick 功能一樣,不過不需要指定輸出文件,自動覆蓋原始圖像文件。
composite: 將一個圖片或多個圖片組合成新圖片。
montage: 組合多個獨立的圖像來創建合成圖像。每個圖像都可以用邊框,透明度等特性進行裝飾。

compare: 從數學和視覺角度比較源圖像與重建圖像之間的差異。
display: 在任何 X server 上顯示一個圖像或圖像序列。
animate: 在任何 X server 上顯示圖像序列。
import: 保存 X server 上的任何可見窗口并把它作為圖像文件輸出。可以捕捉單個窗口,整個屏幕或屏幕的任意矩形部分。
conjure: 解釋并執行 MSL ( Magick Scripting Language ) 寫的腳本。
stream: 一個輕量級工具,用于將圖像或部分圖像的一個或多個像素組件流式傳輸到存儲設備。在處理大圖像或原始像素組件時很有用。

2、命令格式

基本命令的使用,遵循 Unix 風格的標準格式:

command [options] input_image output_image

比如我們將一張寬高 300x300 的圖片 goods.png 轉換成 200x200goods.jpg,可以這樣用

convert -resize 200x200 goods.png goods.jpg
-resize 定義圖片尺寸,ImageMagick 所有的選項參數都在這個【命令行選項手冊】。

但是隨著功能的復雜,命令緩慢擴大成了這樣的格式:

command [options] image1 [options] image2 [options] output_image    

于是上面的命令也可以寫成這樣

convert goods.png -resize 200x200 goods.jpg

筆記:個人建議,如果轉換的是一張圖片,那么用第一種格式,因為像 -density 等一些選項必須放在 commandinput_image 之間,所以為了省記都不寫錯,都寫在 commandinput_image 之間豈不很好。
但是如果是多張圖片轉換,就需要按第二種格式,正確輸出命令選項了。

提示:如果上面的工具命令在計算機上不可以使用,則可以把它們當作 magick 命令的子命令使用,例如

magick identify goods.png
3、指定文件格式

默認情況下 ImageMagick 會讀取圖像中唯一標識格式的簽名來確定文件格式,如果沒有,則根據文件的擴展名來確定格式,如 image.jpg 被認為 jpeg 格式文件,如果都獲取不到,則需要手動指定文件的格式。命令格式為 format:input_or_output_image

輸入文件一般情況應該不需要手動指定文件格式,輸出文件的時候,png 格式分 png8png24 等格式,如果 png8 格式的文件能夠滿足需求,指定合理的格式可以縮小文件的大小,示例如下。

convert goods.png png8:goods_8.png
convert goods.png png24:goods_24.png
實際案例
文中案例基于 ImageMagick 7.0.7
1、生成縮略圖

需求:將一張寬高為 900x600 的圖片 goods.jpg 生成寬高為 150x100 的縮略圖 thumbnail.jpg

convert -resize 150x100 -quality 70 -strip goods.jpg thumbnail.jpg

解釋:

-resize 150x100:定義輸出的縮略圖尺寸為 150x100

-quality 70:降低縮略圖的質量為 70,取值范圍 1 ( 最低圖像質量和最高壓縮率 ) 到 100 ( 最高圖像質量和最低壓縮率 ),默認值根據輸出格式有 7592100,選項適用于 JPEG / MIFF / PNG

-strip:讓縮略圖移除圖片內嵌的所有配置文件,注釋等信息,以減小文件大小。

-resize 延伸解讀,如下。

上面的例子中,輸入的圖片和輸出的圖片比例是一致的,所以不會有特殊情況出現,但是遇到比例不同的時候,上面的寫法并不會得到 150x100 的圖像,而是會根據圖像的寬高比例,取最大值,得出來的結果可能是 150 寬和更小的高,或者 100 高和更小的寬;所以 IamgeMagick 提供了幾種符號來定義縮放。

convert -resize "150x100!" goods.jpg thumbnail.jpg
convert -resize "150x100>" goods.jpg thumbnail.jpg
convert -resize "150x100<" goods.jpg thumbnail.jpg

!:不管圖片寬高如何,都縮放成 150x100 這樣的尺寸。
>:只有寬高均大于 150x100 的圖片才縮放成該尺寸 ( 按比例取最大值 ),小于的圖片不做處理。
<:與 > 功能相反。

提示:因為有些字符是 Linux shell 或其他系統的特殊字符,所以需要用引號包裹起來或者用反斜線 轉義,注意,不同平臺可能引號都是有差異的。

2、添加水印

需求 ① :給圖片居中加上透明文本水印。

convert  -draw "text 0,0 "JD.COM""  -fill "rgba(221, 34, 17, 0.25)"  -pointsize 36  
-font "cochin.ttc"  -gravity center  joy.jpg  watermark.jpg

解釋:

-draw:繪圖選項,text 聲明繪制文本, 0,0聲明文本距離圖片左上角的偏移值, JD.COM聲明繪制的文本,最好用引號包裹起來,避免輸入特殊字符引起錯誤。繪制文本的格式為 text x,y string,當然還可以繪制其他類型,諸如圓 ( circle )、折線 ( polyline )。

-fill:對文本填充顏色,貌似 ImageMagick 命令中前面的選項是用來控制后面的選項的,所以應該把這樣的修飾選項放到 -draw 前面比較好,很重要,后面的案例就是這樣的。

-pointsize:指定文本的字體大小。

-font:指定字體。

-gravity:設置文本在圖片里的排列方式 ( 類似 CSS 里的 align-items + justify-content ),center 表示水平垂直都居中,其他值還可以是:NorthWest, North, NorthEast, West, East, SouthWest, South, SouthEast,不記大小寫。

:反斜線也是類 Unix 系統的續行字符,當一個命令很長時,我們可以把它寫成多行,以便視覺上的美觀和直觀。

需求 ② :給圖片加上傾斜平鋪透明文本水印。

convert  -size 100x100  xc:none  
-fill "#d90f02"  -pointsize 18  -font "cochin.ttc"  
-gravity center  -draw "rotate -45 text 0,0 "JD.COM""  
-resize 60%  miff:-  |  composite  -tile  -dissolve 25  -  joy.jpg  watermark.jpg

解釋:文本平鋪水印其實是將文本畫成一張 png 圖片,然后用這張透明圖片在目標圖片上進行平鋪。

-size:設置畫布的大小。

xc::全稱 X Constant Image,是 canvas:的別名,定義一張畫布,用來繪圖,常用格式為 xc:colornone 或者 transparent 設置畫布為透明底,默認為白色。

-resize:該選項還可以指定百分比,意為縮放至原圖像的百分之幾。貌似 -pointsize 小于 14 后,-draw 里的 rotate 會不生效,所以用 -resize 來把平鋪圖案變得更小。

miff:-

miff: 聲明輸出 ImageMagick ( IM ) 自己的圖像文件格式:MIFF,主要用途是以復雜的方式處理圖像時當做中間保存格式,適用于從一個 IM 命令向另一個 IM 命令傳遞圖像元數據和其他關聯屬性。

- 在管道符前面意為將 IM 命令執行的結果作為標準輸出,在管道符后面則表示從標準輸入中讀取這個數據,如在管道符后面的 composite 中使用 - 讀取剛剛生成的透明圖像。

|Linux shell 管道符,用于將上一個命令的標準輸出傳遞到下一個命令作為標準輸入。這里將生成的水印圖案傳遞給 composite 命令。

-tile:顧名思義,讓圖案平鋪。

-dissolve:設置平鋪圖案的透明度。

圖釋:

3、繪制驗證碼

大概邏輯如下:

隨機生成 4 個英文字母或數字。

創建一個寬高 100x40 的畫布。

設置字體大小為 16,每個字符的寬高也就是 16 左右了,依次計算出每個字符的 x, y 坐標,再增加一丁點旋轉。

隨機創建一條透明曲線,加上噪點,增加圖片被破解的難度(在保證肉眼能看得清楚的用戶體驗下)。

如果需要安全性更高的驗證碼,請了解驗證碼破解原理并做合理調整。

如果加上隨機計算,可能代碼會比較多,所以這里寫成固定值,方便理解。

convert  "xc:[100x40!]"  -pointsize 20  -font "cochin.ttc"  
-gravity NorthWest  -strokewidth 1  
-fill "#b72b36"  -stroke "#b72b36"  -draw "translate 13,19  rotate 10  text -5,-8 "5""  
-fill "#821d70"  -stroke "#821d70"  -draw "translate 36,13  rotate -8  text -8,-8 "C""  
-fill "#c7960a"  -stroke "#c7960a"  -draw "translate 60,23  rotate 5   text -5,-8 "2""  
-fill "#03610a"  -stroke "#03610a"  -draw "translate 85,25  rotate 13  text -8,-8 "E""  
-strokewidth 2  -stroke "rgba(248, 100, 30, 0.5)"  -fill "rgba(0, 0, 0, 0)"  
-draw "bezier  -20,30  -16,10  20,2    50,20"  
-draw "bezier  50,20   78,42   138,36  140,16"  
+noise Impulse  
captcha.jpg

結果:

鑒于字體比較細,可以用 strokewidth 加邊框來加粗,或者使用字體的粗體版本,這里使用了第一種方式。

解釋:

xc:[100x40!]:設置畫布大小的一種簡寫方式,方括號里寫入畫布寬高,注意要加 !,否則會出乎意料喲。

文本定位與旋轉

畫布寬 100px,平均分成 4 分,每份 25px, 文字寬 16px, 得文字 x 的坐標左右擺動范圍為 +0px, +9pxy 坐標同理,用于設置 translate 值。

實際上字體本身并沒有填充滿整個 16x16 的區域,根據字體的不同,填滿的區域可能各有不同,所以根據cochin 字體的特性,上面稍微將字體大小調整為 20,實際渲染出來的字母才是 16x16 左右大小,數字大概是 10x16,所以設置數字的 x,y-5,-8,結合下面兩個屬性解釋 x,y 的計算方式。

translate: 設置文本的橫縱向偏移值。

rotate:設置文本旋轉,單位 degrees。根據 gravity 的設置坐標系統有一丁點變化,所以請設置為 西北(NorthWest) ,表示以畫布 0,0 坐標旋轉,跟 HTML 5 Canvas 坐標系統一致。

根據這樣的坐標系統,如果要文字按自身的中心旋轉,得配合 translatetextx,y 一起使用,原理可參考這篇文章[圖像旋轉的實現],注意 translaterotate 的順序。

strokewidth:設置文本的邊框寬度或線條寬度。

stroke:設置文本的邊框顏色或線條顏色。

-fill "rgba(0, 0, 0, 0)":上面設置了文本的填充顏色,會影響下面的貝塞爾曲線,所以這里指定一個透明的填充色以覆蓋上面的設定,使曲線沒有填充。

bezier:繪制貝塞爾曲線,一兩句話我怕解釋不清楚,所以請大家參考一下維基百科的解釋或者這篇中文文章的解釋,最后再參考一下 IM 官方示例的描述。上面兩條三次貝塞爾曲線的坐標分別表示 起始點起始點的控制點結束點的控制點結束點

+noise:增加噪點,可以使用 convert -list noise 查看當前系統支持哪些算法的噪點,大概有 Gaussian, Impulse, Laplacian, Multiplicative, Poisson, Random, Uniform

4、克隆及拼合圖像
這個案例主要了解幾個基本操作的 API
convert  
(  -crop 300x300+10+25  joy.jpg  )  
(  -resize 400x400  -crop 300x300+50+0  logo:  )  -swap 0,1  +append  
(  -clone 0  -flop  -flip  )  -append  
-resize 200x200  combined.jpg

結果如下:

解釋:

圓括號 ( ... ):圖像堆棧 ( image stack ),相當于創建了一個獨立作用域處理圖像,這個可以使圖像之前的處理互不干擾。圓括號需用反斜杠轉義,才能不被 Shell 當做特殊字符處理,并且每個圓括號兩邊需要用空格隔開。不必要的圓括號會使 IM 增加少許額外的工作,但是卻讓命令更清晰不容易出錯。

-crop:裁剪出圖像的一個或多個矩形區域,格式為 {size}{+-}x{+-}y,如果不指定偏移值 x,y,則會被解釋為按指定寬高切割圖像成多少份(多圖像)。

logo:IM 內置圖像,這個就是上圖中拿著魔法棒的主人公了,本身寬高 640x480,其他內置圖像還有:rose:granite :等,看這里。

-swap

交換圖像的位置,格式 -swap index,index

IM 在圖像處理操作時,實際上很可能是在處理一個圖像列表,當新圖像被讀入或者創建時,IM 會將該新圖像添加到當前圖像列表的末尾。

如上,本來我們的圖像列表里有 2 張圖,第一張是 joy,但是 -swap 0,1 的意思是交換第一張圖與第二張圖的位置,所以 joy 變成跑到后面了。

+append:水平連接當前圖像列表的圖像來創建單個較長的圖像。

-append:垂直連接當前圖像列表的圖像來創建單個較長的圖像。

-clone:克隆圖像,格式為 -clone {index_range_list}

-clone 0:表示克隆圖像列表里的第一張圖像。

-clone 1-2:表示克隆圖像列表里的第二張到第三張圖像。

-clone 0--10 表示第一張圖像,-1 表示最后一張圖像,所以整句命令則表示克隆整個圖像列表。

-clone 2,0,1:表示克隆第三張,第一張,第二張圖像,順序根據指定的索引決定,用逗號分隔。

-flop:將圖像水平翻轉。

-flip:將圖像垂直翻轉。

筆記:

選項之間的順序很重要。

-clone 雷同的選項還有諸如:-delete, -insert, -reverse, -duplicate,用于操作圖像列表,功能與單詞意思相同。

5、GIF 與圖片互轉 5.1、GIF 轉圖片
convert  -coalesce  rain.gif  frame.jpg

-coalesce:根據圖像 -dispose 元數據的設置覆蓋圖像序列中的每個圖像,以重現動畫序列中每個點的動畫效果。下面用一張結果對比圖來解釋這句話。

原始圖 ( rain.gif ) :

結果對比:

5.2、定義輸出文件名

上面默認輸出的文件名為:frame-0.jpg, frame-1.jpg, frame-2.jpg ...
如果想使用下劃線作為符號,輸出為 frame_0.jpg, frame_1.jpg, frame_2.jpg ...,則可以如下設置。

convert  -coalesce  rain.gif  frame_%d.jpg

或者

 convert  -coalesce  -set filename:n "%p"  rain.gif  "frame_%[filename:n].jpg"

解釋:

第一種方式 %dC 語言 printf() 中表示輸出一個整數,參考 -adjoin 選項。

第二種為常規方式。

-set:設置圖像屬性,格式為 -set key value

filename:n "%p":以 filename: 開頭的 key 用于設置輸出文件名的相關信息,如這里使用 filename:n,在輸出文件名時,則可以使用 %[filename:n] 拿到剛剛的設置,而設置的內容則是 "%p""%p" 表示圖像在圖像列表中的索引值,更多百分比選項 ( Percent Escapes ) 參考。

5.3、解析特定幀

如果只想拿到 GIF 的第一幀,可以這樣設置。

convert  -coalesce  "rain.gif[0]"  first_frame.jpg

拿到某些幀,如同 -clone 的寫法。

convert  -coalesce  "rain.gif[0-2]"  some_frames_%d.jpg
5.4、獲取頁數

通過 identify 命令我們可以簡要得到文件的信息,如下。

identify  rain.gif

通過換行符分割,簡單封裝一個 Node.js 函數獲取頁數。

// parser.js
const util = require("util")
const exec = util.promisify(require("child_process").exec)

exports.numberOfPages = async (filePath) => {
  try {
    const { stdout } = await exec(`identify "${filePath}"`)
    return stdout.trim().split("
").length
  } catch (err) {
    throw new Error(err)
  }
}
// main.js
const { numberOfPages } = require("./parser")

;(async function start () {
  const pages = await numberOfPages("rain.gif")
  console.log("pages:", pages)
}())
5.5、圖片轉 GIF
convert  -loop 0  "frame-*.jpg"  rain_animation.gif

將所有與 frame-*.jpg 模式匹配的圖像轉換成一張 GIF 圖像,如 frame-0.jpgframe-1.jpg等。
-loop 設置動畫循環次數,0 表示無限循環。
設置每張圖像的播放速度可以使用 -delay 選項。

筆記:IM 讀取系列文件時,frame-10.jpg 會排在 frame-2.jpg 前面,為獲得圖像正確的讀取順序,可以為文件名設置前導零 ( leading zeros )。如:frame-000.jpg, frame-001.jpg, frame-002.jpg ... frame-010.jpg

所以在生成圖像時,我們可以使用 %03d 獲得三位前導零。

convert  -coalesce  rain.gif  frame-%03d.jpg
6、PDF 與圖片互轉

PDF 與圖片互轉跟 GIF 很相似,稍微有些格式自身需要注意的區別。
IM 本身是不具備解析 PDF 的功能的,需要依賴專門解析這種格式的外部程序,如官方指明的 ghostscript 解析程序。
首先安裝 gs,還是演示 Mac OS 安裝:brew install ghostscript

以 這個PDF 為例,把它轉換成圖片,有兩種方式達到我們想要的結果:

① convert  -density 150  -flatten  "download.pdf[0]"  first_page.jpg
② convert  -density 150  -background white  -alpha remove  download.pdf  download.jpg

解釋:

當轉換 PDF 成 JPG 格式圖像時,某些情況得到的 JPG 圖片會出現黑色背景(轉換成 PNG 不會),所以可以使用 -flatten 選項讓其保持白色背景,但加上這個選項,多頁 PDF 不會分成多個 JPG 圖像,第二種方式 -background white -alpha remove 則可以一次命令轉換多頁 PDF 成多個圖像并保持白色背景。

第二種方式 IM 內部應該是一頁一頁的轉換,所以一個 10 頁的 PDF 耗時會比較久,采用第一種方式讓 Node.js 多進程同時轉換該 PDF 可以提升速率。

-density:指定輸出圖像的分辨率 ( DPI ),在 Mac OS 上,默認的分辨率 ( 72 ) 輸出的圖像字跡不清,需要更高分辨率獲得清晰的圖像。

在 Node.js 中應用
直接通過 child_process 模塊執行相應的命令即可,如下。

只需要結果可以使用 exec

const util = require("util")
const exec = util.promisify(require("child_process").exec)

;(async function start () {
  try {
    await exec(`convert -resize "150x100!" -strip goods.jpg thumbnail.jpg`)
    console.log("convert completed.")
  } catch (err) {
    console.log("convert failed.", err)
  }
}())

流式輸入輸出可以使用 spawn

const cp = require("child_process")
const fs = require("fs")

const args = [
  "-",  // 使用標準輸入
  "-resize", "150x100!",
  "-strip",
  "jpg:-",  // 輸出到標準輸出
]

const streamIn = fs.createReadStream("/path/to/goods.jpg")
const proc = cp.spawn("convert", args)
streamIn.pipe(proc.stdin)
proc.stdout.pipe(HttpResponse)
最后

本文同步發表于【凹凸實驗室】博客及微信公眾號,歡迎關注我們,么么噠。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108039.html

相關文章

  • 用 Matplotlib 庫生成動畫圖表

    摘要:相對于靜態圖表,人類總是容易被動畫和交互式圖表所吸引。可以使用輕松生成圖表直方圖功率譜,條形圖,錯誤圖表,散點圖等。然而,也有一些方面落后于同類的庫。動畫使用一組固定的對象。稍后將用數據對行對象進行填充。現在用將它們轉換為動畫。 翻譯:瘋狂的技術宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...

    call_me_R 評論0 收藏0
  • 用 Matplotlib 庫生成動畫圖表

    摘要:相對于靜態圖表,人類總是容易被動畫和交互式圖表所吸引。可以使用輕松生成圖表直方圖功率譜,條形圖,錯誤圖表,散點圖等。然而,也有一些方面落后于同類的庫。動畫使用一組固定的對象。稍后將用數據對行對象進行填充。現在用將它們轉換為動畫。 翻譯:瘋狂的技術宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...

    不知名網友 評論0 收藏0
  • GraphicsMagick 學習筆記

    摘要:兩種最常用的圖片處理工具或,是的分支,這兩個圖片處理工具功能基本相同,各有特色。但他們并不是的插件,它們都是客戶端軟件,和版的都有。在中有一個插件叫,它完成了對上述兩個工具的封裝,使用的方式調用。 兩種最常用的圖片處理工具:GraphicsMagick 或 ImageMagick,GM是IM的分支,這兩個圖片處理工具功能基本相同,各有特色。但他們并不是nodejs的插件,它們都是客戶端...

    chenatu 評論0 收藏0

發表評論

0條評論

youkede

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<