golang高性能图像处理插件库bimg的使用

Golang高性能图像处理插件库bimg的使用

bimg是一个小型Go包,用于通过C绑定使用libvips进行快速高级图像处理,提供简单的编程API。

特性

bimg支持以下图像操作:

  • 调整大小
  • 裁剪(包括智能裁剪支持,需要libvips 8.5+)
  • 旋转(基于EXIF方向自动旋转)
  • 翻转(基于EXIF元数据自动翻转)
  • 镜像
  • 缩放
  • 缩略图
  • 提取区域
  • 水印(使用文本或图像)
  • 高斯模糊效果
  • 自定义输出色彩空间(RGB、灰度等)
  • 格式转换(带有额外的质量/压缩设置)
  • EXIF元数据(大小、alpha通道、配置文件、方向等)
  • 修剪(需要libvips 8.6+)

安装

安装bimg

go get -u github.com/h2non/bimg

安装libvips

需要先安装libvips 8.3+(推荐8.8+):

# 官方推荐安装方式(已弃用脚本安装)
# 请参考:https://libvips.github.io/libvips/install.html

示例代码

基本使用

import (
  "fmt"
  "os"
  "github.com/h2non/bimg"
)

调整大小

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Resize(800, 600)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

size, err := bimg.NewImage(newImage).Size()
if size.Width == 800 && size.Height == 600 {
  fmt.Println("The image size is valid")
}

bimg.Write("new.jpg", newImage)

旋转

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Rotate(90)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

bimg.Write("new.jpg", newImage)

格式转换

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Convert(bimg.PNG)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

if bimg.NewImage(newImage).Type() == "png" {
  fmt.Fprintln(os.Stderr, "The image was converted into png")
}

强制调整大小(不保持宽高比)

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).ForceResize(1000, 500)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

size := bimg.Size(newImage)
if size.Width != 1000 || size.Height != 500 {
  fmt.Fprintln(os.Stderr, "Incorrect image size")
}

自定义色彩空间(黑白)

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Colourspace(bimg.INTERPRETATION_B_W)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

colourSpace, _ := bimg.ImageInterpretation(newImage)
if colourSpace != bimg.INTERPRETATION_B_W {
  fmt.Fprintln(os.Stderr, "Invalid colour space")
}

自定义选项

options := bimg.Options{
  Width:        800,
  Height:       600,
  Crop:         true,
  Quality:      95,
  Rotate:       180,
  Interlace:    true,
}

buffer, err := bimg.Read("image.jpg")
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("new.jpg", newImage)

水印

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

watermark := bimg.Watermark{
  Text:       "Chuck Norris (c) 2315",
  Opacity:    0.25,
  Width:      200,
  DPI:        100,
  Margin:     150,
  Font:       "sans bold 12",
  Background: bimg.Color{255, 255, 255},
}

newImage, err := bimg.NewImage(buffer).Watermark(watermark)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

bimg.Write("new.jpg", newImage)

流式接口

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

image := bimg.NewImage(buffer)

// 首先裁剪图像
_, err := image.CropByWidth(300)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

// 然后翻转它
newImage, err := image.Flip()
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

// 保存裁剪和翻转后的图像
bimg.Write("new.jpg", newImage)

性能

bimg使用libvips进行图像处理,内存占用低,通常比使用最快的ImageMagick和GraphicsMagick设置或Go原生image包快4倍,在某些情况下处理JPEG图像甚至快8倍。

调试

运行程序时传递DEBUG环境变量:

DEBUG=bimg ./app

启用libvips跟踪(注意会在stdout中写入大量数据):

VIPS_TRACE=1 ./app

许可证

MIT - Tomas Aparicio


更多关于golang高性能图像处理插件库bimg的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang高性能图像处理插件库bimg的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang高性能图像处理插件库bimg使用指南

bimg是一个基于libvips的Go语言图像处理库,提供了高性能的图像处理能力。相比传统的图像处理库,bimg在处理大图时内存占用更低,速度更快。

安装bimg

首先需要安装libvips库,然后安装bimg:

# Ubuntu/Debian
sudo apt-get install libvips-dev

# macOS
brew install vips

# 安装bimg
go get -u github.com/h2non/bimg

基本使用

1. 读取和保存图像

package main

import (
	"io/ioutil"
	"log"
	"github.com/h2non/bimg"
)

func main() {
	// 读取图像文件
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	// 创建bimg图像对象
	image := bimg.NewImage(buf)

	// 保存图像
	err = ioutil.WriteFile("output.jpg", buf, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

2. 调整图像大小

func resizeImage() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	options := bimg.Options{
		Width:   800,
		Height:  600,
		Quality: 95,
	}

	newImage, err := bimg.NewImage(buf).Process(options)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile("resized.jpg", newImage, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

3. 裁剪图像

func cropImage() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	options := bimg.Options{
		Width:   400,
		Height:  400,
		Crop:    true,  // 启用裁剪
		Quality: 90,
		Gravity: bimg.GravityCentre, // 从中心裁剪
	}

	newImage, err := bimg.NewImage(buf).Process(options)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile("cropped.jpg", newImage, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

4. 格式转换

func convertFormat() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	options := bimg.Options{
		Type:    bimg.WEBP, // 转换为webp格式
		Quality: 80,
	}

	newImage, err := bimg.NewImage(buf).Process(options)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile("output.webp", newImage, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

5. 获取图像元数据

func getMetadata() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	image := bimg.NewImage(buf)
	
	size, err := image.Size()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Image size: %dx%d", size.Width, size.Height)

	metadata, err := image.Metadata()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Format: %s, Orientation: %d", metadata.Format, metadata.Orientation)
}

高级功能

1. 添加水印

func addWatermark() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	watermark := bimg.Watermark{
		Text:       "Copyright (c) 2023",
		Opacity:    0.5,
		Width:      200,
		DPI:        100,
		Margin:     50,
		Font:      "sans bold 12",
		Background: bimg.Color{R: 255, G: 255, B: 255},
	}

	options := bimg.Options{
		Watermark: watermark,
		Quality:   90,
	}

	newImage, err := bimg.NewImage(buf).Process(options)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile("watermarked.jpg", newImage, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

2. 图像旋转

func rotateImage() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	options := bimg.Options{
		Rotate: 90, // 旋转90度
	}

	newImage, err := bimg.NewImage(buf).Process(options)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile("rotated.jpg", newImage, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

3. 图像锐化

func sharpenImage() {
	buf, err := ioutil.ReadFile("input.jpg")
	if err != nil {
		log.Fatal(err)
	}

	options := bimg.Options{
		Sharpen: bimg.Sharpen{
			Radius:    1,
			X1:        2,
			Y2:        10,
			Y3:        20,
			M1:        1,
			M2:        2,
		},
		Quality: 90,
	}

	newImage, err := bimg.NewImage(buf).Process(options)
	if err != nil {
		log.Fatal(err)
	}

	err = ioutil.WriteFile("sharpened.jpg", newImage, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

性能优化技巧

  1. 批量处理:对于大量图像处理,可以使用goroutine池来并发处理
  2. 复用缓冲区:对于频繁的图像处理操作,可以复用内存缓冲区
  3. 合理设置缓存:bimg内部使用libvips的缓存机制,可以通过环境变量调整缓存大小
  4. 选择合适的质量:根据实际需求调整图像质量参数,避免不必要的质量损失或过大文件
func batchProcess() {
	files := []string{"1.jpg", "2.jpg", "3.jpg"}
	results := make(chan error, len(files))

	for _, file := range files {
		go func(f string) {
			buf, err := ioutil.ReadFile(f)
			if err != nil {
				results <- err
				return
			}

			options := bimg.Options{
				Width:   800,
				Height:  600,
				Quality: 85,
			}

			newImage, err := bimg.NewImage(buf).Process(options)
			if err != nil {
				results <- err
				return
			}

			output := "resized_" + f
			err = ioutil.WriteFile(output, newImage, 0644)
			results <- err
		}(file)
	}

	for range files {
		if err := <-results; err != nil {
			log.Println("Error processing:", err)
		}
	}
}

bimg是一个功能强大且高性能的图像处理库,特别适合需要处理大量图像或大尺寸图像的场景。通过合理使用其提供的各种选项和功能,可以实现复杂的图像处理需求。

回到顶部