Go 實驗室:image 圖像處理就用它

短腿子猿的 Go 實驗室,Golang 官方提供了很多 package 來幫助大家提高開發的效率,但是由於函數太多,經常會記不住,這裏開了一個專題來分享官方 package,努力做到每週一更

Golang 中的 image 包提供了基本的圖像類型、顏色模型、以及用於處理圖像的各種函數和接口。以下是一些常用的函數和接口,以及相應的示例。

常用類型與接口

image.Image 接口

這是 Go 語言中處理圖像的核心接口,定義了所有圖像必須實現的方法:

type Image interface {
    // Bounds returns the domain for which At can return non-zero color.
    // The bounds do not necessarily contain the point (0, 0).
    Bounds() Rectangle

    // At returns the color of the pixel at (x, y).
    // At must panic if x or y are outside the bounds of the image.
    At(x, y int) color.Color
}

color.Color 接口

表示一種顏色,需要實現以下方法:

type Color interface {
    // RGBA returns the alpha-premultiplied red, green, blue and alpha values
    // for the color. Each value ranges within [0, 0xffff], but is represented
    // by a uint32 so that multiplying by a blend factor up to 0xffff will not
    // overflow.
    RGBA() (r, g, b, a uint32)
}

color.RGBA 結構體

實現了color.Color接口,代表一個由紅綠藍透明度組成的顏色:

type RGBA struct {
    R, G, B, A uint8
}

image.Decode

從輸入流(如文件或網絡連接)解碼圖像,並返回一個實現了 image.Image 接口的對象:

func Decode(r io.Reader) (img image.Image, err error)

示例:

file, err := os.Open("example.png")
if err != nil {
    panic(err)
}
defer file.Close()

img, _, err := image.Decode(file)
if err != nil {
    panic(err)
}
// 使用解碼後的img進行後續操作

image.DecodeConfig

僅解碼圖像的配置信息而不加載完整圖像數據:

func DecodeConfig(r io.Reader) (cfg image.Config, err error)

示例:

file, err := os.Open("example.gif")
if err != nil {
    panic(err)
}
defer file.Close()

config, err := image.DecodeConfig(file)
if err != nil {
    panic(err)
}
fmt.Printf("Image dimensions: %d x %d, Color model: %v\n", config.Width, config.Height, config.ColorModel)

簡單示例

這裏是用一些官方包來縮放以及改變圖片大小

func main() {
    // 讀取原圖
    file, err := os.Open("input.jpeg")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    img, err := jpeg.Decode(file)
    if err != nil {
        panic(err)
    }

    width := 600
    height := 400

    // 創建一個新的圖片,大小爲指定的寬和高
    newImg := image.NewRGBA(image.Rect(0, 0, width, height))

    // 裁剪圖片   使用 draw.Draw 簡單縮放(質量較低,可能會出現像素化)
    draw.Draw(newImg, newImg.Bounds(), img, image.Point{}, draw.Src)

    // 重新編碼並保存
    outputFile, err := os.Create("output.jpg")
    if err != nil {
        panic(err)
    }
    defer outputFile.Close()

    // 設置壓縮選項
    outputQuality := 80
    opts := &jpeg.Options{
        Quality: outputQuality,
    }
    err = jpeg.Encode(outputFile, newImg, opts)
    if err != nil {
        panic(err)
    }

}

這個示例中,我們使用 draw.Src 方式將原圖直接繪製到目標圖像上,這相當於最簡單的像素複製,可能會導致圖像質量下降,特別是對於縮小操作時,會出現明顯的像素化現象。這種方法適用於對圖像質量要求不高的場景,或者作爲臨時解決方案。

請注意,這種方法並不推薦用於高質量的圖像縮放,因爲它沒有采用任何插值算法來平滑過渡像素,導致縮放後的圖像質量較差。對於實際項目中對圖像大小調整的需求,建議使用專門的圖像處理庫如 github.com/nfnt/resize它提供了多種高質量的插值算法(如 Lanczos 等),能夠更好地保持圖像細節和視覺效果。

總結

這些只是image包中的一部分功能。根據實際需求,還可以使用其他子包(如image/jpeg, image/png, image/gif等)進行特定格式的編碼和解碼,或利用image/draw包進行更復雜的圖像合成操作。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/UvJsI2b8afBNMi-6007MZA?poc_token=HAWQXmajWH4tczqL6TmtLNfKvlB_xE_Dfpew4grA