【Go語言繪圖】圖片的旋轉
阿新 • • 發佈:2020-12-16
在上一篇中,我們瞭解了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