1. 程式人生 > >【Go語言繪圖】圖片的旋轉

【Go語言繪圖】圖片的旋轉

在上一篇中,我們瞭解了gg庫的基本使用,包括調整大小、調整圓形引數、設定顏色、儲存圖片、載入圖片和裁剪。這一篇我們來學習一下圖片的旋轉。 ## 載入圖片 首先,我們先來一張黃圖。 ```go func TestRotateImage(t *testing.T) { width := 1000 height := 1000 dc := gg.NewContext(width, height) dc.DrawRectangle(0, 0, float64(width), float64(width)) dc.SetRGB255(255, 255, 0) dc.Fill() dc.SavePNG("test.png") } ``` ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203344479-1080759299.png) 然後載入好我們要旋轉的圖片,用的仍舊是我們上一篇中使用的圖。 ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203354915-1468592596.png) ```go func TestRotateImage(t *testing.T) { im, err := gg.LoadImage("/Users/bytedance/Desktop/test.png") if err != nil { panic(err) } w := im.Bounds().Size().X h := im.Bounds().Size().Y width := 2 * w height := 2 * h dc := gg.NewContext(width, height) dc.DrawRectangle(0, 0, float64(width), float64(width)) dc.SetRGB255(255, 255, 0) dc.Fill() dc.DrawImage(im, width/4, height/4) dc.SavePNG("test.png") } ``` 這裡為了更好的看到旋轉的效果,對之前的程式碼做了一些調整。把畫布大小設定為2倍圖片的長寬。 ```go width := 2 * w height := 2 * h dc := gg.NewContext(width, height) ``` 然後繪製了一個矩形,並且將它的顏色填充為黃色(因為圖片比較白,用黑色背景更容易看到邊界)。 ```go dc.DrawRectangle(0, 0, float64(2*h), float64(2*w)) dc.SetRGB255(255, 255, 0) dc.Fill() ``` 順便糾正一下上一篇中的遺漏的點,使用 `setRGB()` 方法來設定顏色確實需要使用轉換函式來將RGB值進行對映,但還有另一個方法 `SetRGB255()` 可以直接設定RGB值,就不需要先進行一次轉換了。 然後我們將圖片載入到了正中心的位置,`(w/4,h/4)` 對應圖片左上角在畫布上的位置。 ```go dc.DrawImage(im, width/4, height/4) ``` 輸出的圖片如下: ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203510580-1320990544.png) ## 旋轉圖片 圖片載入好了,下面我們開始新增一個旋轉操作。 ```go func TestRotateImage(t *testing.T) { im, err := gg.LoadImage("/Users/bytedance/Desktop/test.png") if err != nil { panic(err) } w := im.Bounds().Size().X h := im.Bounds().Size().Y width := 2 * w height := 2 * h dc := gg.NewContext(width, height) dc.DrawRectangle(0, 0, float64(width), float64(width)) dc.SetRGB255(255, 255, 0) dc.Fill() dc.Rotate(45) dc.DrawImage(im, width/4, height/4) dc.SavePNG("test.png") } ``` 其實只添加了一行程式碼,就是在載入圖片前先呼叫了 `Rotate()` 方法。想象之中,我們會把圖片旋轉45度,但實際上是這樣的: ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203521848-1120354491.png) 好像不太符合預期,實際上,仔細研究一下就會發現,這裡的旋轉是圍繞原點也就是整個畫布的左上角進行旋轉的,那我想要它圍繞中心點旋轉該怎麼辦呢?別慌,換一個方法就可以了。`RotateAbout()` 方法可以指定圖片的旋轉中心點,換這個來試試看: ```go func TestRotateImage(t *testing.T) { im, err := gg.LoadImage("/Users/bytedance/Desktop/test.png") if err != nil { panic(err) } w := im.Bounds().Size().X h := im.Bounds().Size().Y width := 2 * w height := 2 * h dc := gg.NewContext(width, height) dc.DrawRectangle(0, 0, float64(width), float64(width)) dc.SetRGB255(255, 255, 0) dc.Fill() dc.RotateAbout(45, float64(width/2), float64(height/2)) dc.DrawImage(im, width/4, height/4) dc.SavePNG("test.png") } ``` ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203537948-688471293.png) 這下圖片確實繞中心點旋轉了,但轉45度好像不應該是這樣的,再來看看這個方法的說明: ``` // RotateAbout updates the current matrix with a clockwise rotation. // Rotation occurs about the specified point. Angle is specified in radians. ``` 可以看到,第一個引數的意思其實代表的是弧度,而不是角度,所以想要旋轉45度當然不能這麼傳,我們換一個姿勢再試試。 ```go func TestRotateImage(t *testing.T) { im, err := gg.LoadImage("/Users/bytedance/Desktop/test.png") if err != nil { panic(err) } w := im.Bounds().Size().X h := im.Bounds().Size().Y width := 2 * w height := 2 * h dc := gg.NewContext(width, height) dc.DrawRectangle(0, 0, float64(width), float64(width)) dc.SetRGB255(255, 255, 0) dc.Fill() dc.RotateAbout(gg.Radians(45), float64(width/2), float64(height/2)) dc.DrawImage(im, width/4, height/4) dc.SavePNG("test.png") } ``` ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203550491-1314745854.png) 這下終於得到了我們想要的圖。 ## 總結 圖片旋轉其實很簡單,只需要在繪製前呼叫 `Rotate()` 或 `RotateAbout()` 方法即可。但需要注意幾點: 1. 旋轉是順時針旋轉 2. `Rotate` 方法是繞左上角旋轉 3. 第一個引數都代表的是弧度而不是角度 這樣旋轉我們也能掌握了,圖片處理功能又進了一步。喜歡本文的朋友歡迎點贊收藏加關注~ ![](https://img2020.cnblogs.com/blog/1043143/202012/1043143-20201216203602911-14075692