在Go語言中,正弦函數由 math 包提供,函數入口為 math.Sin,正弦函數的引數為 float64,返回值也是 float64。在使用正弦函數時,根據實際精度可以進行轉換。
Go語言的標準庫支援對圖片畫素進行存取,並且支援輸出各種圖片格式,如 JPEG、PNG、GIF 等。
首先給出本節完整的程式碼:
package main
import (
"image"
"image/color"
"image/png"
"log"
"math"
"os"
)
func main() {
// 圖片大小
const size = 300
// 根據給定大小建立灰度圖
pic := image.NewGray(image.Rect(0, 0, size, size))
// 遍歷每個畫素
for x := 0; x < size; x++ {
for y := 0; y < size; y++ {
// 填充為白色
pic.SetGray(x, y, color.Gray{255})
}
}
// 從0到最大畫素生成x坐標
for x := 0; x < size; x++ {
// 讓sin的值的範圍在0~2Pi之間
s := float64(x) * 2 * math.Pi / size
// sin的幅度為一半的畫素。向下偏移一半畫素並翻轉
y := size/2 - math.Sin(s)*size/2
// 用黑色繪製sin軌跡
pic.SetGray(x, int(y), color.Gray{0})
}
// 建立檔案
file, err := os.Create("sin.png")
if err != nil {
log.Fatal(err)
}
// 使用png格式將資料寫入檔案
png.Encode(file, pic) //將image資訊寫入檔案中
// 關閉檔案
file.Close()
}
設定圖片背景色
以下是設定圖片背景的程式碼:
// 圖片大小
const size = 300
// 根據給定大小建立灰度圖
pic := image.NewGray(image.Rect(0, 0, size, size))
// 遍歷每個畫素
for x := 0; x < size; x++ {
for y := 0; y < size; y++ {
// 填充為白色
pic.SetGray(x, y, color.Gray{255})
}
}
程式碼說明如下:
-
第 2 行,宣告一個 size 常數,值為 300。
-
第 5 行,使用 image 包的 NewGray() 函數建立一個圖片物件,使用區域由 image.Rect 結構提供,image.Rect 描述一個方形的兩個定位點 (x1,y1) 和 (x2,y2),image.Rect(0,0,size,size) 表示使用完整灰度影象素,尺寸為寬 300,長 300。
-
第 8 行和第 9 行,遍歷灰度圖的所有畫素。
-
第 11 行,將每一個畫素的灰度設為 255,也就是白色。
灰度圖是一種常見的圖片格式,一般情況下顏色由 8 位組成,灰度範圍為 0~255,0 表示黑色,255 表示白色。
初始化好的灰度圖預設的灰度值都是 0,對的是黑色,由於顯示效果的效果不是很好,所以這裡將所有畫素設定為 255,也就是白色。
繪製正弦函數軌跡
正弦函數是一個週期函數,定義域是實數集,取值範圍是 [-1, 1]。用程式設計的通俗易懂的話來說就是:math.Sin 函數的引數支援任意浮點數範圍,函數返回值的範圍總是在 -1~1 之間(包含 1、-1)。
要將正弦函數放在圖片上需要考慮以下一些因素:
-
math.Sin 的返回值在 -1~1 之間,需要考慮將正弦的輸出幅度變大,可以將 math.Sin 的返回值乘以一個常數進行放大。
-
圖片的坐標系原點在左上角,而 math.Sin 基於笛卡爾坐標系原點在左下角,需要對影象進行上下翻轉和平移。
將這些處理邏輯匯總為程式碼如下:
// 從0到最大畫素生成x坐標
for x := 0; x < size; x++ {
// 讓sin的值的範圍在0~2Pi之間
s := float64(x) * 2 * math.Pi / size
// sin的幅度為一半的畫素。向下偏移一半畫素並翻轉
y := size/2 - math.Sin(s)*size/2
// 用黑色繪製sin軌跡
pic.SetGray(x, int(y), color.Gray{0})
}
程式碼說明如下:
1) 第 2 行,生成 0 到 size(300)的 x 坐標軸。
2) 第 5 行,計算 math.Sin 的定義域,這段程式碼等效為:
rate := x / size
s := rate * 2 * math.Pi
x 的範圍是 0 到 size,因此除以 size 後,rate 的範圍是 0~1 之間,再乘以 2π 後,s 的範圍剛好是 0~2π 之間。
float64(x) 表示將整型的 x 變數轉換為 float64 型別,之後運算的所有表示式將以 float64 型別進行。
3) 第 8 行中,math.Sin(s)*size/2 表示將正弦函數的返回值幅度從 1 擴大到二分之一的 size。負號表示將正弦函數圖形以圖形中心上下翻轉。疊加 size/2 表示將圖形在 y 軸上向下偏移二分之一的 size(圖片坐標系的 y 向下)。
4) 第 11 行將計算好的 x 軸和 y 軸資料,以灰度為 0(黑色)使用 SetGray() 方法填充到畫素中。
寫入圖片的正弦函數影象如下圖所示: