Go 語言高效能影像處理神器 h2non/bimg
推薦背景
日常業務開發中常會遇到各種影像處理需求,如,圖片大小調整、翻轉、旋轉、提取大小、加水印、圖片模糊化,格式轉換,修剪等等;影像處理根據業務需求一部分影像處理需求在前端完成,如,使用者裁剪編輯,打馬賽克,美化,色彩調整;使用者傳完圖片後的邏輯在後端處理,此時就會用到影像處理相關的方法;Go 語言標準庫提供的 image 能夠處理最基本的影像處理任務,但個性化的影像處理任務還是得自己實現。
當標準庫無法滿足日常開發的需求時候,推薦使用 h2non/bimg ,它能夠快速高效完成各種高階影像處理任務。
h2non/bimg 是什麼
h2non/bimg 是基於 C 語言的 libvips 庫封裝的高階影像處理的 Go 包;它的效能極高,所佔記憶體也很小,通常比 ImageMagick, GraphicsMagick,Go 標準庫快 4 倍,在某些情況下,處理 JPEG 影像的速度甚至比它們快 8 倍。
bimg uses internally libvips, a powerful library written in C for image processing which requires a low memory footprint and it's typically 4x faster than using the quickest ImageMagick and GraphicsMagick settings or Go native image package, and in some cases it's even 8x faster processing JPEG images.
h2non/bimg 提供以下出片處理 API:
- 調整大小
- 放大
- 裁剪(包括智慧裁剪支援,libvips 8.5+)
- 旋轉(根據 EXIF 方向自動旋轉)
- 翻轉(具有基於 EXIF 後設資料的自動翻轉)
- 翻轉
- 縮圖
- 獲取大小
- 水印(使用文字或影像)
- 高斯模糊效果
- 自定義輸出顏色空間(RGB,灰度...)
- 格式轉換以及壓縮處理
- EXIF 後設資料(大小,Alpha 通道,配置檔案,方向...)修改
- 修剪(libvips 8.6+)
h2non/bimg 能夠將影像輸出為 JPEG、PNG 和 WEBP 格式,包括在它們之間進行格式轉換。
怎麼使用
h2non/bimg 因為基於 C 語言的 libvips 庫,因此使用要滿足以下幾個條件:
- libvips 8.3+ (8.8+ recommended)
- C compatible compiler such as gcc 4.6+ or clang 3.0+
- Go 1.3+
提示:
安裝
- 建立一個測試專案
# 建立專案目錄
$ mkdir bimg
# 切換到專案根目錄
$ cd bimg
# 初始化專案
$ go mod init bimg
- 獲取 h2non/bimg 包
$ go get -u github.com/h2non/bimg
通常會報錯,提示需要依賴 libvips ;因此,先安裝 libvips,再獲取 h2non/bimg 包。
mac 安裝執行 $ brew install vips
即可自動載入安裝配置;其他系統版本請參考 libvips document 。
再次嘗試獲取 h2non/bimg 包,通常會提示 invalid flag in pkg-config --cflags: -Xpreprocessor
;此時 CGO_FLAGS 授權,即執行一下命令:
$ export CGO_CFLAGS_ALLOW=-Xpreprocessor
再次嘗試獲取 h2non/bimg 包時,會成功獲取包。
開始使用
在專案根目錄建立 main.go
檔案,並準備兩張測試圖片;分別是原始圖片 example.png :
以及用作水印的圖片和 logo.png
:
開始編寫示例:
package main
import (
"fmt"
"os"
"github.com/h2non/bimg"
)
func main() {
imgPath := "example.png"
// 列印影像的後設資料
meta_data := metaData(imgPath)
fmt.Printf("影像型別:%v\n影像尺寸:%v x %v\n", meta_data.Type, meta_data.Size.Width, meta_data.Size.Height)
// 調整影像大小
resize(imgPath, 1200, 800)
// 旋轉影像,傳旋轉角度
rotate(imgPath, 180)
// 自動(隨機)影像,根據 EXIF 方向後設資料(autoRotateOnly)自動旋轉
autoRotate(imgPath)
// 格式轉換
convert(imgPath, bimg.JPEG)
// 新增文字水印
watermarkText(imgPath)
// 新增圖片水印
logoPath := "logo.png"
watermarkImage(imgPath, logoPath)
// 高斯模糊,模糊程度引數
gaussianBlur(imgPath, 20, 5)
// 按長寬式縮略
smartCrop(imgPath, 400, 300)
// 縮圖,縮圖畫素 200 * 200
thumbnail(imgPath, 200)
// 獲取影像型別
imgType := getType(imgPath)
fmt.Printf("影像型別:%v\n", imgType)
}
列印影像的後設資料
func metaData(path string) bimg.ImageMetadata {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
metaData, err := bimg.Metadata(buffer)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
return metaData
}
調整影像大小
func resize(path string, width, height int) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
newImage, err := bimg.NewImage(buffer).Resize(width, height)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
_, err = bimg.NewImage(newImage).Size()
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("001-resize.jpg", newImage)
}
指定角度旋轉
func rotate(path string, angle bimg.Angle) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
// 傳旋轉角度
newImage, err := bimg.NewImage(buffer).Rotate(angle)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("002-rotate.png", newImage)
}
自動旋轉
func autoRotate(path string) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
newImage, err := bimg.NewImage(buffer).AutoRotate()
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("003-auto-rotate.jpg", newImage)
}
格式轉換
func convert(path string, imageType bimg.ImageType) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
newImage, err := bimg.NewImage(buffer).Convert(imageType)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("004-convert."+bimg.ImageTypes[imageType], newImage)
}
文字水印
func watermarkText(path string) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
// 水印的相關資料
watermark := bimg.Watermark{
Text: "GoCN 社群",
DPI: 150,
Margin: 300,
Opacity: 0.25, // 不透明度
Width: 500,
Font: "sans bold 14",
Background: bimg.Color{255, 255, 255},
}
newImage, err := bimg.NewImage(buffer).Watermark(watermark)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("005-watermark.jpg", newImage)
}
圖片水印
func watermarkImage(path, logo string) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
logoBuffer, err := bimg.Read(logo)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
// 水印的相關資料
watermark := bimg.WatermarkImage{
Left: 100,
Top: 200,
Buf: logoBuffer,
Opacity: 1, // 不透明度 0~1 之間的浮點數
}
newImage, err := bimg.NewImage(buffer).WatermarkImage(watermark)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("006-watermark-image.jpg", newImage)
}
高斯模糊
func gaussianBlur(path string, sigma, minAmpl float64) {
options := bimg.Options{
GaussianBlur: bimg.GaussianBlur{sigma, minAmpl},
}
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
newImage, err := bimg.NewImage(buffer).Process(options)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("007-gaussianblur.jpg", newImage)
}
指定長寬縮圖像
func smartCrop(path string, width, height int) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
newImage, err := bimg.NewImage(buffer).SmartCrop(width, height)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("008-smartCrop.jpg", newImage)
}
縮圖像
func thumbnail(path string, pixels int) {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
newImage, err := bimg.NewImage(buffer).Thumbnail(pixels)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
bimg.Write("009-thumbnail.jpg", newImage)
}
獲取型別
func getType(path string) string {
buffer, err := bimg.Read(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
typeName := bimg.NewImage(buffer).Type()
return typeName
}
執行專案
執行以下命令:
$ go run main.go
執行成功,專案目錄下生成影像處理結果,效果如下:
想了解更多。
總結
h2non/bimg 目前 Github Go 影像處理類包中 Star 數量最多,高效能的影像處理包; h2non/bimg 足夠應付日常影像處理類業務需求,使用很方便,也可以在改包基礎上功能擴充套件開發滿足更多個性化的業務開發需求。
參考資料
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go 語言異常處理Go
- Go 語言處理 yaml 檔案GoYAML
- GitHub - cshum/imagor: Go語言編寫的快速影像處理伺服器GithubGo伺服器
- Go 語言操作 MySQL 之 預處理GoMySql
- Go語言基礎-錯誤處理Go
- Go語言錯誤處理機制Go
- go語言處理TCP拆包/粘包GoTCP
- Go 語言的錯誤訊息處理Go
- GO語言手動處理TCP粘包GoTCP
- [ gev ] Go 語言優雅處理 TCP “粘包”GoTCP
- Go語言處理—Day11—反射機制Go反射
- 使用Go語言每分鐘處理1百萬請求Go
- Go語言常用字串處理方法總結Go字串
- Go語言的 序列處理 和 並行處理 有什麼區別 ?Go並行
- 語言處理器
- Python自然語言處理 1 語言處理與PythonPython自然語言處理
- 使用Go語言每分鐘處理100萬請求Go
- 使用Go語言每分鐘處理一百萬個請求Go
- go語言高效能快取元件ccache分析Go快取元件
- ants——Go語言的高效能協程池Go
- 從錯誤處理看 Rust 的語言和 Go 語言的設計RustGo
- 自然語言處理(NLP)自然語言處理
- 影像處理--影像特效特效
- Go語言之錯誤處理Go
- Go語言(golang)的錯誤(error)處理的推薦方案GolangError
- Go語言 如何配製 高效能sql.DBGoSQL
- webgl 影像處理2---影像畫素處理Web
- 自然語言處理(NLP)概述自然語言處理
- 自然語言處理NLP(四)自然語言處理
- Python自然語言處理Python自然語言處理
- .NET 8 高效能跨平臺影像處理庫 ImageSharp
- NLP 與 NLU:從語言理解到語言處理
- Python自然語言處理 3 處理原始文字Python自然語言處理
- Go語言————1、初識GO語言Go
- Python影像處理丨5種影像處理特效Python特效
- 影像預處理
- go 語言 proxy.golang.org timeout 無法訪問 處理方法Golang
- 自然語言處理(NLP)系列(一)——自然語言理解(NLU)自然語言處理