Go 图像处理

Golang中的image包提供了基本的图像类型、颜色模型、以及用于处理图像的各种函数和接口。

常用类型与接口

image.Image 接口

这是Go语言中处理图像的核心接口,定义了所有图像必须实现的方法:

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 接口

表示一种颜色,需要实现以下方法:

Go 复制代码
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接口,代表一个由红绿蓝透明度组成的颜色:

Go 复制代码
type RGBA struct {
    R, G, B, A uint8
}

image.Decode

从输入流(如文件或网络连接)解码图像,并返回一个实现了image.Image接口的对象:

Go 复制代码
func Decode(r io.Reader) (img image.Image, err error)
Go 复制代码
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

仅解码图像的配置信息而不加载完整图像数据:

Go 复制代码
func DecodeConfig(r io.Reader) (cfg image.Config, err error)
Go 复制代码
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)

案例

Go 复制代码
package main

import (
	"image"
	"image/draw"
	"image/jpeg"
	"os"
)

func main() {
	// 读取原图
	file, err := os.Open("需要时jpeg格式的才行.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包进行更复杂的图像合成操作。

使用第三方包处理

imaging一个简单、实用的图像处理工具

文档:

安装

go get github.com/disintegration/imaging

Go 复制代码
package main

import (
	"github.com/disintegration/imaging"
	"log"
)

func main() {
	// 打开一个图片文件
	src, err := imaging.Open("./1716282750475.jpg")
	if err != nil {
		log.Fatalf("无法打开图像: %v", err)
	}

	// 生成缩略图
	dst := imaging.Thumbnail(src, 100, 100, imaging.Lanczos)

	// 保存
	err = imaging.Save(dst, "thumbnail.jpg")
	if err != nil {
		log.Fatalf("无法保存图像: %v", err)
	} else {
		log.Println("保存图像成功")
	}
}
相关推荐
JustHappy3 分钟前
古法编程秘籍(七):互联网到底是什么?把两台电脑怎么说话搞懂就够了
前端·后端·网络协议
snow@li7 分钟前
SEO-文章标题:写文章时候,分类+主标题+大纲+解释 作为标题 / 不点进去也知道全文覆盖什么 / 标题即架构
前端
kyriewen1 小时前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
小和尚同志1 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
老马识途2.02 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕2 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@2 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#4 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar4 小时前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github
weixin_471383034 小时前
Taro-02-页面路由
前端·taro