最近接了個比較大的需求,須要作不少圖片處理的事情,好比圖片的旋轉裁截拼接,各類漸變處理,文字排列,一開始光是想一想就頭疼。但沒有辦法,既然已經需求已經到手上了,那就得把它作好才行,因而便開始被迫營業,無證上崗了。git
通過一番查找,找到了一個Go語言圖片處理的庫,通過調研發現還挺強的,能知足需求,因而決定寫點文章,記錄一下使用心得,以便往後不時之需。github
使用以前,咱們固然得先來安裝一下這個庫:app
go get -u github.com/fogleman/gg
這個庫的一個好處是有不少測試代碼,能夠拿來跑跑看,就知道它大概能實現什麼樣的效果了。測試
這是它例子的大概效果圖,能夠看到,能實現的圖形效果仍是挺多的。.net
咱們拿其中的一個代碼來簡單體驗一下:3d
package main import "github.com/fogleman/gg" func main() { dc := gg.NewContext(1000, 1000) dc.DrawCircle(500, 500, 400) dc.SetRGB(0, 0, 0) dc.Fill() dc.SavePNG("out.png") }
duang 的一下,一張黑不溜秋的圓形圖就生成了。code
關於上面的代碼,下面會進行逐一說明。對象
dc := gg.NewContext(1000, 1000)
這是先初始化一個 Context
對象,使用庫以前都須要先初始化一個 Context
對象,後面的兩個 1000
,分別對應着最終生成圖片的寬度和高度。咱們能夠修改一下高度爲 500
看看效果。blog
dc := gg.NewContext(1000, 500)
能夠看到圖片被腰斬了,高度矮了一半,一樣修改寬度參數也能夠獲得相似的效果,這裏就不演示了。圖片
dc.DrawCircle(500, 500, 400)
這裏是畫一個圓心位置在 (500,500)
,半徑爲 400
的圓形。須要說明的一點是,這裏的座標軸是以左上角爲原點的,水平向右是橫軸正方向,豎直向下是縱軸正方向,因此(500,500)
正是中心位置。咱們能夠調整一下參數值來看下效果。
dc := gg.NewContext(1000, 1000) dc.DrawCircle(300, 300, 400)
能夠看到,圓心往左上角移動了。還能夠調整一下半徑參數試試:
dc := gg.NewContext(1000, 1000) dc.DrawCircle(300, 300, 300)
這樣咱們又獲得了一個完整的圓。
dc.SetRGB(0, 0, 0) dc.Fill()
這兩句的意思是先設置顏色值爲 (0,0,0)
,也就是黑色,乍眼一看這三個值分別對應的是顏色的 R、G、B
值,但實際上徹底不是這麼回事,這裏須要注意的是,這三個值分別表明紅色、綠色、藍色的程度,因此若是分別設置爲,會獲得下面的三張圖。
那若是想要根據RGB值來設置顏色該怎麼處理呢?其實也很簡單,作一個壓縮映射便可,RGB
值的範圍是0~255,表示的含義也是對應色值的程度,這裏不過將範圍變成了0~1,那咱們將須要使用到的值除以255就能夠獲得對應的映射值了。具體的顏色RGB值跟顏色的對應關係能夠在網上搜到。
https://tool.oschina.net/commons?type=3
下面咱們用淡黃色作一個例子,對應的 RGB
值是 (255,222,173)
,咱們添加一下映射轉換的代碼便可:
var rbgConverter = func(r []float64) []float64 { result := make([]float64, 0) for i := 0; i < len(r); i++ { result = append(result, r[i] / 255) } return result } func main() { dc := gg.NewContext(1000, 1000) dc.DrawCircle(500, 500, 400) rgb := []float64{255,222,173} newRgb := rbgConverter(rgb) dc.SetRGB(newRgb[0], newRgb[1], newRgb[2]) dc.Fill() dc.SavePNG("out.png") }
這樣咱們就獲得了一張黃圖。
dc.SavePNG("out.png")
SavePNG()
方法能夠將當前圖形保存成 PNG
格式文件,路徑能夠是相對路徑,也能夠是絕對路徑。
SaveJPG()
方法能夠將當前圖形保存成 JPG
格式文件。
固然,這裏的兩個方法其實也只是包裝了一下,點進代碼能夠看到,裏面並無什麼奇奇怪怪的邏輯。
// SavePNG encodes the image as a PNG and writes it to disk. func (dc *Context) SavePNG(path string) error { return SavePNG(path, dc.im) } func SavePNG(path string, im image.Image) error { file, err := os.Create(path) if err != nil { return err } defer file.Close() return png.Encode(file, im) }
因此,咱們也能夠根據本身的須要將圖片保存成其它格式或者存到其它地方。
加載圖片有三個方法能夠實現,LoadPNG()
用來加載 PNG
格式的圖片,LoadJPG()
用來加載 JPG
格式的圖片,若是不清楚該用什麼方法,能夠直接使用 LoadImage()
方法來加載圖片。
加載圖片後,獲得的是一個 image.Image
對象,能夠經過該對象來獲取圖片的一些基本信息,如:圖片的長和寬、圖片某一點的顏色RGB值。
加載圖片以後,能夠使用 DrawImage()
方法來將圖片繪製出來,以便用於後續操做。
im, err := gg.LoadImage("/Users/bytedance/Desktop/test.jpg") if err != nil { panic(err) } w := im.Bounds().Size().X h := im.Bounds().Size().Y dc := gg.NewContext(h, w) dc.DrawImage(im, 0, 0)
有一個常常使用到的方法叫 Clip()
,該方法能夠將圖像進行裁剪,裁剪的形狀取決於以前畫的圖形。
下面來舉個例子,這是咱們要裁剪的圖,咱們用一個圓形來對它進行裁剪。
func main() { // 加載圖片,這裏路徑換成本身的 im, err := gg.LoadImage("test.jpg") if err != nil { panic(err) } // 獲取圖片的寬度和高度 w := im.Bounds().Size().X h := im.Bounds().Size().Y dc := gg.NewContext(h, w) // 取寬度和高度的最小值做爲直徑 radius := math.Min(float64(w), float64(h)) / 2 // 畫圓形 dc.DrawCircle(float64(w/2), float64(h/2), radius) // 對畫布進行裁剪 dc.Clip() // 加載圖片 dc.DrawImage(im, 0, 0) dc.SavePNG("out.png") }
這樣一來,頭像就作好了【手動狗頭】。
Go 語言也能夠實現對圖片進行不少類型的操做,今天主要介紹了圖片的加載、保存、繪製圓形、調整大小和顏色以及裁剪。以後還會進一步介紹其它功能。
我以爲若是不是須要使用並無熟悉它的必要,但知道有這麼個東西,知道它能實現什麼樣的效果,可讓你手上的牌又多了一張,之後有須要的時候便不至於捉襟見肘了。因此還在等什麼,趕忙點贊收藏加關注吧~