image - 2D 图像处理
image 包实现了基本的 2D 图像库,提供了图像接口、颜色模型和几何形状的表示。
概述
image 包是 Go 语言图像处理的核心库,定义了图像的基本接口和数据结构。它与 image/color、image/png、image/jpeg 等包配合使用,可以解码、编码和操作各种格式的图像。
包导入:
import "image"
基本使用:
// 1. 创建新图像
img := image.NewRGBA(image.Rect(0, 0, 100, 100))
// 2. 设置像素颜色
img.Set(50, 50, color.RGBA{255, 0, 0, 255})
// 3. 获取像素颜色
c := img.At(50, 50)
// 4. 解码图像
decoded, format, _ := image.Decode(reader)
// 5. 获取图像配置
config, format, _ := image.DecodeConfig(reader)
典型示例:
示例 1:创建渐变图像:
package main
import (
"image"
"image/color"
"image/png"
"os"
)
func main() {
// 创建 256x256 的 RGBA 图像
img := image.NewRGBA(image.Rect(0, 0, 256, 256))
// 绘制渐变
for y := 0; y < 256; y++ {
for x := 0; x < 256; x++ {
img.Set(x, y, color.RGBA{
R: uint8(x),
G: uint8(y),
B: 128,
A: 255,
})
}
}
// 保存为 PNG
f, _ := os.Create("gradient.png")
defer f.Close()
png.Encode(f, img)
}
运行:
$ go run main.go
# 生成 gradient.png 文件
示例 2:读取图像信息:
package main
import (
"fmt"
"image"
_ "image/jpeg"
_ "image/png"
"os"
)
func main() {
f, err := os.Open("test.jpg")
if err != nil {
panic(err)
}
defer f.Close()
// 只解码配置信息(不加载像素数据)
config, format, err := image.DecodeConfig(f)
if err != nil {
panic(err)
}
fmt.Printf("格式:%s\n", format)
fmt.Printf("宽度:%d\n", config.Width)
fmt.Printf("高度:%d\n", config.Height)
fmt.Printf("颜色模型:%T\n", config.ColorModel)
}
运行:
$ go run main.go
格式:jpeg
宽度:1920
高度:1080
颜色模型:color.Model
示例 3:图像裁剪:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 创建原图
src := image.NewRGBA(image.Rect(0, 0, 100, 100))
// 填充红色
for y := 0; y < 100; y++ {
for x := 0; x < 100; x++ {
src.Set(x, y, color.RGBA{255, 0, 0, 255})
}
}
// 裁剪子图像
sub := src.SubImage(image.Rect(25, 25, 75, 75))
fmt.Printf("原图大小:%v\n", src.Bounds())
fmt.Printf("子图大小:%v\n", sub.Bounds())
// 子图像与原图共享像素数据
sub.Set(0, 0, color.RGBA{0, 255, 0, 255})
fmt.Printf("原图 (25,25) 颜色:%v\n", src.At(25, 25))
}
运行:
$ go run main.go
原图大小:(0,0)-(100,100)
子图大小:(25,25)-(75,75)
原图 (25,25) 颜色:{0 255 0 255}
一、核心接口(按字母顺序)
Image 接口
Image
定义:
type Image interface {
ColorModel() color.Model
Bounds() Rectangle
At(x, y int) color.Color
}
说明:
- 图像的基本接口
- 表示一个有限矩形的颜色网格
- 所有图像类型都实现此接口
方法:
ColorModel() color.Model- 返回颜色模型Bounds() Rectangle- 返回图像边界At(x, y int) color.Color- 返回指定像素的颜色
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 创建图像
var img image.Image = image.NewRGBA(image.Rect(0, 0, 100, 100))
// 使用接口方法
fmt.Printf("边界:%v\n", img.Bounds())
fmt.Printf("颜色模型:%T\n", img.ColorModel())
fmt.Printf("像素 (0,0): %v\n", img.At(0, 0))
}
运行:
$ go run main.go
边界:(0,0)-(100,100)
颜色模型:color.RGBAModel
像素 (0,0): {0 0 0 0}
PalettedImage 接口
PalettedImage
定义:
type PalettedImage interface {
ColorIndexAt(x, y int) uint8
Image
}
说明:
- 调色板图像接口
- 颜色来自有限的调色板
- 继承 Image 接口
方法:
- 继承 Image 接口的所有方法
ColorIndexAt(x, y int) uint8- 返回调色板索引
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 创建调色板
palette := color.Palette{
color.RGBA{255, 0, 0, 255},
color.RGBA{0, 255, 0, 255},
color.RGBA{0, 0, 255, 255},
}
// 创建调色板图像
img := image.NewPaletted(image.Rect(0, 0, 10, 10), palette)
// 设置调色板索引
img.SetColorIndex(0, 0, 0) // 红色
img.SetColorIndex(1, 0, 1) // 绿色
img.SetColorIndex(2, 0, 2) // 蓝色
// 获取索引
fmt.Printf("索引 (0,0): %d\n", img.ColorIndexAt(0, 0))
fmt.Printf("索引 (1,0): %d\n", img.ColorIndexAt(1, 0))
fmt.Printf("索引 (2,0): %d\n", img.ColorIndexAt(2, 0))
}
运行:
$ go run main.go
索引 (0,0): 0
索引 (1,0): 1
索引 (2,0): 2
RGBA64Image 接口
RGBA64Image
定义:
type RGBA64Image interface {
RGBA64At(x, y int) color.RGBA64
Image
}
说明:
- Go 1.17+ 新增接口
- 返回 64 位 RGBA 颜色值
- 避免类型转换开销
方法:
- 继承 Image 接口的所有方法
RGBA64At(x, y int) color.RGBA64- 返回 64 位颜色值
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 创建图像
img := image.NewRGBA64(image.Rect(0, 0, 10, 10))
// 设置 64 位颜色
img.SetRGBA64(0, 0, color.RGBA64{
R: 0xFFFF,
G: 0x0000,
B: 0x0000,
A: 0xFFFF,
})
// 获取 64 位颜色
c := img.RGBA64At(0, 0)
fmt.Printf("RGBA64: R=%04x G=%04x B=%04x A=%04x\n", c.R, c.G, c.B, c.A)
}
运行:
$ go run main.go
RGBA64: R=ffff G=0000 B=0000 A=ffff
二、图像类型(按字母顺序)
Alpha 类型
Alpha
定义:
type Alpha struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 8 位 Alpha 通道图像
- 每个像素 1 字节(0-255)
- 用于透明度蒙版
构造函数:
NewAlpha(r Rectangle) *Alpha
方法:
AlphaAt(x, y int) color.Alpha- 获取 Alpha 值At(x, y int) color.Color- 获取颜色Bounds() Rectangle- 获取边界ColorModel() color.Model- 获取颜色模型Opaque() bool- 检查是否不透明PixOffset(x, y int) int- 获取像素偏移量RGBA64At(x, y int) color.RGBA64- 获取 64 位颜色Set(x, y int, c color.Color)- 设置颜色SetAlpha(x, y int, c color.Alpha)- 设置 Alpha 值SetRGBA64(x, y int, c color.RGBA64)- 设置 64 位颜色SubImage(r Rectangle) Image- 获取子图像
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 创建 Alpha 图像
alpha := image.NewAlpha(image.Rect(0, 0, 100, 100))
// 设置渐变透明度
for y := 0; y < 100; y++ {
for x := 0; x < 100; x++ {
alpha.SetAlpha(x, y, color.Alpha{A: uint8(x)})
}
}
fmt.Printf("Alpha (0,0): %d\n", alpha.AlphaAt(0, 0).A)
fmt.Printf("Alpha (99,99): %d\n", alpha.AlphaAt(99, 99).A)
fmt.Printf("是否不透明:%v\n", alpha.Opaque())
}
运行:
$ go run main.go
Alpha (0,0): 0
Alpha (99,99): 99
是否不透明:false
Alpha16 类型
Alpha16
定义:
type Alpha16 struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 16 位 Alpha 通道图像
- 每个像素 2 字节(大端格式)
- 高精度透明度
构造函数:
NewAlpha16(r Rectangle) *Alpha16
方法:
Alpha16At(x, y int) color.Alpha16- 获取 16 位 Alpha 值- 其他方法与 Alpha 类似
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
alpha16 := image.NewAlpha16(image.Rect(0, 0, 100, 100))
// 设置 16 位 Alpha 值
alpha16.SetAlpha16(0, 0, color.Alpha16{A: 0xFFFF})
alpha16.SetAlpha16(1, 0, color.Alpha16{A: 0x8000})
fmt.Printf("Alpha16 (0,0): %04x\n", alpha16.Alpha16At(0, 0).A)
fmt.Printf("Alpha16 (1,0): %04x\n", alpha16.Alpha16At(1, 0).A)
}
运行:
$ go run main.go
Alpha16 (0,0): ffff
Alpha16 (1,0): 8000
CMYK 类型
CMYK
定义:
type CMYK struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- CMYK 颜色空间图像
- 用于印刷四分色模式
- Cyan(青)、Magenta(品红)、Yellow(黄)、Key(黑)
构造函数:
NewCMYK(r Rectangle) *CMYK
方法:
CMYKAt(x, y int) color.CMYK- 获取 CMYK 值SetCMYK(x, y int, c color.CMYK)- 设置 CMYK 值- 其他标准方法
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
cmyk := image.NewCMYK(image.Rect(0, 0, 100, 100))
// 设置 CMYK 颜色(纯青色)
cmyk.SetCMYK(0, 0, color.CMYK{
C: 255,
M: 0,
Y: 0,
K: 0,
})
c := cmyk.CMYKAt(0, 0)
fmt.Printf("CMYK: C=%d M=%d Y=%d K=%d\n", c.C, c.M, c.Y, c.K)
}
运行:
$ go run main.go
CMYK: C=255 M=0 Y=0 K=0
Gray 类型
Gray
定义:
type Gray struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 8 位灰度图像
- 每个像素 1 字节(0-255)
- 用于黑白图像处理
构造函数:
NewGray(r Rectangle) *Gray
方法:
GrayAt(x, y int) color.Gray- 获取灰度值SetGray(x, y int, c color.Gray)- 设置灰度值- 其他标准方法
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
gray := image.NewGray(image.Rect(0, 0, 256, 256))
// 创建灰度渐变
for y := 0; y < 256; y++ {
for x := 0; x < 256; x++ {
gray.SetGray(x, y, color.Gray{Y: uint8(x)})
}
}
fmt.Printf("Gray (0,0): %d\n", gray.GrayAt(0, 0).Y)
fmt.Printf("Gray (255,255): %d\n", gray.GrayAt(255, 255).Y)
}
运行:
$ go run main.go
Gray (0,0): 0
Gray (255,255): 255
Gray16 类型
Gray16
定义:
type Gray16 struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 16 位灰度图像
- 每个像素 2 字节(大端格式)
- 高精度灰度
构造函数:
NewGray16(r Rectangle) *Gray16
方法:
Gray16At(x, y int) color.Gray16- 获取 16 位灰度值SetGray16(x, y int, c color.Gray16)- 设置灰度值
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
gray16 := image.NewGray16(image.Rect(0, 0, 100, 100))
gray16.SetGray16(0, 0, color.Gray16{Y: 0xFFFF})
gray16.SetGray16(1, 0, color.Gray16{Y: 0x8000})
fmt.Printf("Gray16 (0,0): %04x\n", gray16.Gray16At(0, 0).Y)
fmt.Printf("Gray16 (1,0): %04x\n", gray16.Gray16At(1, 0).Y)
}
运行:
$ go run main.go
Gray16 (0,0): ffff
Gray16 (1,0): 8000
NRGBA 类型
NRGBA
定义:
type NRGBA struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 非预乘 Alpha 的 RGBA 图像
- 颜色分量与 Alpha 独立
- PNG 格式使用此格式
构造函数:
NewNRGBA(r Rectangle) *NRGBA
方法:
NRGBAAt(x, y int) color.NRGBA- 获取 NRGBA 值SetNRGBA(x, y int, c color.NRGBA)- 设置 NRGBA 值
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
nrgba := image.NewNRGBA(image.Rect(0, 0, 100, 100))
// 设置半透明红色(非预乘)
nrgba.SetNRGBA(0, 0, color.NRGBA{
R: 255,
G: 0,
B: 0,
A: 128,
})
c := nrgba.NRGBAAt(0, 0)
fmt.Printf("NRGBA: R=%d G=%d B=%d A=%d\n", c.R, c.G, c.B, c.A)
}
运行:
$ go run main.go
NRGBA: R=255 G=0 B=0 A=128
NRGBA64 类型
NRGBA64
定义:
type NRGBA64 struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 64 位非预乘 Alpha 图像
- 每个通道 16 位
构造函数:
NewNRGBA64(r Rectangle) *NRGBA64
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
nrgba64 := image.NewNRGBA64(image.Rect(0, 0, 100, 100))
nrgba64.SetNRGBA64(0, 0, color.NRGBA64{
R: 0xFFFF,
G: 0x0000,
B: 0x0000,
A: 0x8000,
})
c := nrgba64.NRGBA64At(0, 0)
fmt.Printf("NRGBA64: R=%04x G=%04x B=%04x A=%04x\n", c.R, c.G, c.B, c.A)
}
运行:
$ go run main.go
NRGBA64: R=ffff G=0000 B=0000 A=8000
Paletted 类型
Paletted
定义:
type Paletted struct {
Pix []uint8
Stride int
Rect Rectangle
Palette color.Palette
}
说明:
- 调色板图像
- 像素值为调色板索引
- 最多 256 色
构造函数:
NewPaletted(r Rectangle, palette color.Palette) *Paletted
方法:
ColorIndexAt(x, y int) uint8- 获取索引SetColorIndex(x, y int, index uint8)- 设置索引
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 创建 4 色调色板
palette := color.Palette{
color.RGBA{255, 255, 255, 255}, // 白
color.RGBA{128, 128, 128, 255}, // 灰
color.RGBA{0, 0, 0, 255}, // 黑
color.RGBA{255, 0, 0, 255}, // 红
}
img := image.NewPaletted(image.Rect(0, 0, 4, 4), palette)
// 绘制棋盘格
for y := 0; y < 4; y++ {
for x := 0; x < 4; x++ {
if (x+y)%2 == 0 {
img.SetColorIndex(x, y, 0) // 白
} else {
img.SetColorIndex(x, y, 2) // 黑
}
}
}
fmt.Printf("调色板大小:%d\n", len(img.Palette))
fmt.Printf("索引 (0,0): %d\n", img.ColorIndexAt(0, 0))
fmt.Printf("索引 (1,0): %d\n", img.ColorIndexAt(1, 0))
}
运行:
$ go run main.go
调色板大小:4
索引 (0,0): 0
索引 (1,0): 2
RGBA 类型
RGBA
定义:
type RGBA struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 最常用的图像类型
- 每个像素 4 字节(R、G、B、A)
- Alpha 预乘格式
构造函数:
NewRGBA(r Rectangle) *RGBA
方法:
RGBAAt(x, y int) color.RGBA- 获取 RGBA 值Set(x, y int, c color.Color)- 设置颜色SetRGBA(x, y int, c color.RGBA)- 设置 RGBA 值PixOffset(x, y int) int- 获取像素偏移量SubImage(r Rectangle) Image- 获取子图像
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
rgba := image.NewRGBA(image.Rect(0, 0, 100, 100))
// 设置红色像素
rgba.Set(50, 50, color.RGBA{255, 0, 0, 255})
c := rgba.RGBAAt(50, 50)
fmt.Printf("RGBA: R=%d G=%d B=%d A=%d\n", c.R, c.G, c.B, c.A)
// 获取像素偏移量
offset := rgba.PixOffset(50, 50)
fmt.Printf("Pix 偏移量:%d\n", offset)
}
运行:
$ go run main.go
RGBA: R=255 G=0 B=0 A=255
Pix 偏移量:20200
RGBA64 类型
RGBA64
定义:
type RGBA64 struct {
Pix []uint8
Stride int
Rect Rectangle
}
说明:
- 64 位 RGBA 图像
- 每个通道 16 位(大端格式)
- 高精度颜色
构造函数:
NewRGBA64(r Rectangle) *RGBA64
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
rgba64 := image.NewRGBA64(image.Rect(0, 0, 100, 100))
rgba64.SetRGBA64(0, 0, color.RGBA64{
R: 0xFFFF,
G: 0x8000,
B: 0x0000,
A: 0xFFFF,
})
c := rgba64.RGBA64At(0, 0)
fmt.Printf("RGBA64: R=%04x G=%04x B=%04x A=%04x\n", c.R, c.G, c.B, c.A)
}
运行:
$ go run main.go
RGBA64: R=ffff G=8000 B=0000 A=ffff
Uniform 类型
Uniform
定义:
type Uniform struct {
C color.Color
}
说明:
- 纯色图像
- 所有像素都是同一颜色
- 用于背景填充
预定义变量:
Black- 黑色White- 白色Transparent- 透明
示例:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
// 使用预定义的纯色
fmt.Printf("白色:%v\n", image.White.C)
fmt.Printf("黑色:%v\n", image.Black.C)
fmt.Printf("透明:%v\n", image.Transparent.C)
// 创建自定义纯色
red := &image.Uniform{color.RGBA{255, 0, 0, 255}}
fmt.Printf("红色:%v\n", red.C)
// 获取颜色(任何坐标都一样)
fmt.Printf("At(0,0): %v\n", red.At(0, 0))
fmt.Printf("At(100,100): %v\n", red.At(100, 100))
}
运行:
$ go run main.go
白色:{255 255 255 255}
黑色:{0 0 0 0}
透明:{0 0 0 0}
红色:{255 0 0 255}
At(0,0): {255 0 0 255}
At(100,100): {255 0 0 255}
YCbCr 类型
YCbCr
定义:
type YCbCr struct {
Y, Cb, Cr []uint8
YStride, CStride int
Rect Rectangle
SubsampleRatio YCbCrSubsampleRatio
}
说明:
- YCbCr 颜色空间
- 用于视频和 JPEG 压缩
- 亮度(Y)和色度(Cb、Cr)分离
构造函数:
NewYCbCr(r Rectangle, ratio YCbCrSubsampleRatio) *YCbCr
示例:
package main
import (
"fmt"
"image"
)
func main() {
// 创建 YCbCr 图像(4:2:0 子采样)
ycbcr := image.NewYCbCr(image.Rect(0, 0, 100, 100), image.YCbCrSubsampleRatio420)
fmt.Printf("Y 通道长度:%d\n", len(ycbcr.Y))
fmt.Printf("Cb 通道长度:%d\n", len(ycbcr.Cb))
fmt.Printf("Cr 通道长度:%d\n", len(ycbcr.Cr))
fmt.Printf("子采样:%v\n", ycbcr.SubsampleRatio)
}
运行:
$ go run main.go
Y 通道长度:10000
Cb 通道长度:2500
Cr 通道长度:2500
子采样:4:2:0
三、几何类型(按字母顺序)
Point 类型
Point
定义:
type Point struct {
X, Y int
}
说明:
- 2D 点坐标
- X 向右增加,Y 向下增加
构造函数:
Pt(x, y int) Point- 便捷函数
方法:
Add(p Point) Point- 向量加法Sub(p Point) Point- 向量减法In(r Rectangle) bool- 检查是否在矩形内
示例:
package main
import (
"fmt"
"image"
)
func main() {
// 创建点
p1 := image.Point{2, 1}
p2 := image.Pt(3, 2)
// 向量运算
p3 := p1.Add(p2)
p4 := p1.Sub(p2)
fmt.Printf("p1: %v\n", p1)
fmt.Printf("p1 + p2: %v\n", p3)
fmt.Printf("p1 - p2: %v\n", p4)
// 检查点是否在矩形内
r := image.Rect(0, 0, 5, 5)
fmt.Printf("p1 在矩形内:%v\n", p1.In(r))
}
运行:
$ go run main.go
p1: (2,1)
p1 + p2: (5,3)
p1 - p2: (-1,-1)
p1 在矩形内:true
Rectangle 类型
Rectangle
定义:
type Rectangle struct {
Min, Max Point
}
说明:
- 轴对齐矩形
- Min 是左上角,Max 是右下角
- 包含 Min,不包含 Max
构造函数:
Rect(x0, y0, x1, y1 int) Rectangle- 便捷函数
方法:
Add(p Point) Rectangle- 平移矩形Empty() bool- 检查是否为空Eq(r Rectangle) bool- 检查是否相等In(r Rectangle) bool- 检查是否在另一个矩形内Intersect(r Rectangle) Rectangle- 交集Union(r Rectangle) Rectangle- 并集Overlaps(r Rectangle) bool- 检查是否重叠Size() Point- 获取尺寸Dx() int- 宽度Dy() int- 高度
示例:
package main
import (
"fmt"
"image"
)
func main() {
// 创建矩形
r1 := image.Rect(0, 0, 100, 100)
r2 := image.Rect(50, 50, 150, 150)
fmt.Printf("r1: %v\n", r1)
fmt.Printf("r2: %v\n", r2)
// 基本属性
fmt.Printf("r1 宽度:%d\n", r1.Dx())
fmt.Printf("r1 高度:%d\n", r1.Dy())
fmt.Printf("r1 尺寸:%v\n", r1.Size())
// 交集和并集
fmt.Printf("交集:%v\n", r1.Intersect(r2))
fmt.Printf("并集:%v\n", r1.Union(r2))
// 平移
fmt.Printf("r1 平移 (10,10): %v\n", r1.Add(image.Pt(10, 10)))
// 重叠检查
fmt.Printf("r1 和 r2 重叠:%v\n", r1.Overlaps(r2))
}
运行:
$ go run main.go
r1: (0,0)-(100,100)
r2: (50,50)-(150,150)
r1 宽度:100
r1 高度:100
r1 尺寸:(100,100)
交集:(50,50)-(100,100)
并集:(0,0)-(150,150)
r1 平移 (10,10): (10,10)-(110,110)
r1 和 r2 重叠:true
四、核心函数(按字母顺序)
Decode - 解码图像
Decode(r io.Reader) (Image, string, error)
说明:
- 从 io.Reader 解码图像
- 返回 Image、格式名称和错误
- 需要预先注册格式解码器
定义:
func Decode(r io.Reader) (Image, string, error)
示例:
package main
import (
"fmt"
"image"
_ "image/png"
"os"
)
func main() {
f, err := os.Open("test.png")
if err != nil {
panic(err)
}
defer f.Close()
img, format, err := image.Decode(f)
if err != nil {
panic(err)
}
fmt.Printf("格式:%s\n", format)
fmt.Printf("边界:%v\n", img.Bounds())
}
DecodeConfig - 解码配置
DecodeConfig(r io.Reader) (Config, string, error)
说明:
- 只解码颜色模型和尺寸
- 不加载像素数据
- 用于快速获取图像信息
定义:
func DecodeConfig(r io.Reader) (Config, string, error)
示例:
package main
import (
"fmt"
"image"
_ "image/jpeg"
"os"
)
func main() {
f, err := os.Open("photo.jpg")
if err != nil {
panic(err)
}
defer f.Close()
config, format, err := image.DecodeConfig(f)
if err != nil {
panic(err)
}
fmt.Printf("格式:%s\n", format)
fmt.Printf("宽度:%d\n", config.Width)
fmt.Printf("高度:%d\n", config.Height)
fmt.Printf("颜色模型:%T\n", config.ColorModel)
}
NewAlpha - 创建 Alpha 图像
*NewAlpha(r Rectangle) Alpha
说明:
- 创建新的 Alpha 图像
- 自动分配 Pix 切片
示例:
alpha := image.NewAlpha(image.Rect(0, 0, 100, 100))
NewAlpha16 - 创建 Alpha16 图像
*NewAlpha16(r Rectangle) Alpha16
说明:
- 创建新的 16 位 Alpha 图像
NewCMYK - 创建 CMYK 图像
*NewCMYK(r Rectangle) CMYK
说明:
- 创建新的 CMYK 图像
NewGray - 创建灰度图像
*NewGray(r Rectangle) Gray
说明:
- 创建新的 8 位灰度图像
NewGray16 - 创建 Gray16 图像
*NewGray16(r Rectangle) Gray16
说明:
- 创建新的 16 位灰度图像
NewNRGBA - 创建 NRGBA 图像
*NewNRGBA(r Rectangle) NRGBA
说明:
- 创建新的非预乘 Alpha 图像
NewNRGBA64 - 创建 NRGBA64 图像
*NewNRGBA64(r Rectangle) NRGBA64
说明:
- 创建新的 64 位非预乘 Alpha 图像
NewPaletted - 创建调色板图像
*NewPaletted(r Rectangle, palette color.Palette) Paletted
说明:
- 创建新的调色板图像
- 需要指定调色板
NewRGBA - 创建 RGBA 图像
*NewRGBA(r Rectangle) RGBA
说明:
- 创建新的 RGBA 图像
- 最常用的图像类型
示例:
rgba := image.NewRGBA(image.Rect(0, 0, 100, 100))
NewRGBA64 - 创建 RGBA64 图像
*NewRGBA64(r Rectangle) RGBA64
说明:
- 创建新的 64 位 RGBA 图像
NewYCbCr - 创建 YCbCr 图像
*NewYCbCr(r Rectangle, ratio YCbCrSubsampleRatio) YCbCr
说明:
- 创建新的 YCbCr 图像
- 需要指定子采样比例
RegisterFormat - 注册格式
RegisterFormat(name, magic string, decode func(io.Reader) (Image, error), decodeConfig func(io.Reader) (Config, string, error))
说明:
- 注册图像格式解码器
- name: 格式名称(如 “png”)
- magic: 魔数(文件头标识)
- decode: 解码函数
- decodeConfig: 配置解码函数
示例:
// 通常由 image/png 等包自动注册
import _ "image/png"
五、使用场景
场景 1:生成验证码图像
package main
import (
"image"
"image/color"
"image/png"
"math/rand"
"os"
)
func main() {
// 创建图像
img := image.NewRGBA(image.Rect(0, 0, 200, 60))
// 填充背景
for y := 0; y < 60; y++ {
for x := 0; x < 200; x++ {
img.Set(x, y, color.RGBA{
R: uint8(rand.Intn(256)),
G: uint8(rand.Intn(256)),
B: uint8(rand.Intn(256)),
A: 255,
})
}
}
// 保存
f, _ := os.Create("captcha.png")
defer f.Close()
png.Encode(f, img)
}
场景 2:图像缩略图
package main
import (
"image"
"image/jpeg"
"image/png"
"os"
)
func createThumbnail(inputPath, outputPath string, width, height int) error {
// 打开原图
f, err := os.Open(inputPath)
if err != nil {
return err
}
defer f.Close()
// 解码
src, _, err := image.Decode(f)
if err != nil {
return err
}
// 创建缩略图
bounds := src.Bounds()
thumb := image.NewRGBA(image.Rect(0, 0, width, height))
// 简单的缩放(实际应使用插值算法)
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
srcX := x * bounds.Dx() / width
srcY := y * bounds.Dy() / height
thumb.Set(x, y, src.At(srcX, srcY))
}
}
// 保存
out, err := os.Create(outputPath)
if err != nil {
return err
}
defer out.Close()
return jpeg.Encode(out, thumb, &jpeg.Options{Quality: 80})
}
场景 3:图像水印
package main
import (
"image"
"image/color"
"image/png"
"os"
)
func addWatermark(base image.Image, text string) image.Image {
bounds := base.Bounds()
// 创建新图像
result := image.NewRGBA(bounds)
// 复制原图
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
result.Set(x, y, base.At(x, y))
}
}
// 绘制水印文字(简化版,实际应使用 draw 包)
for y := bounds.Max.Y - 30; y < bounds.Max.Y; y++ {
for x := bounds.Max.X - 100; x < bounds.Max.X; x++ {
c := result.At(x, y)
r, g, b, a := c.RGBA()
// 增加亮度
result.Set(x, y, color.RGBA{
R: uint8(r >> 8),
G: uint8(g >> 8),
B: uint8(b >> 8),
A: uint8(a >> 8),
})
}
}
return result
}
六、快速参考
图像类型对比
| 类型 | 位深 | 用途 | 内存 |
|---|---|---|---|
| Gray | 8 位 | 灰度图 | 1 字节/像素 |
| Gray16 | 16 位 | 高精度灰度 | 2 字节/像素 |
| RGBA | 32 位 | 常规彩色 | 4 字节/像素 |
| RGBA64 | 64 位 | 高精度彩色 | 8 字节/像素 |
| NRGBA | 32 位 | PNG 格式 | 4 字节/像素 |
| CMYK | 32 位 | 印刷 | 4 字节/像素 |
| YCbCr | 可变 | 视频/JPEG | 1.5-3 字节/像素 |
| Paletted | 8 位索引 | GIF | 1 字节/像素 |
几何类型方法
| 类型 | 方法 | 说明 |
|---|---|---|
| Point | Add, Sub, In | 向量运算、包含检查 |
| Rectangle | Dx, Dy, Size | 尺寸获取 |
| Rectangle | Intersect, Union | 集合运算 |
| Rectangle | Overlaps, In, Empty | 关系检查 |
构造函数
| 函数 | 返回类型 | 说明 |
|---|---|---|
| NewRGBA | *RGBA | 创建 RGBA 图像 |
| NewRGBA64 | *RGBA64 | 创建 64 位 RGBA |
| NewNRGBA | *NRGBA | 创建非预乘 Alpha |
| NewGray | *Gray | 创建灰度图 |
| NewPaletted | *Paletted | 创建调色板图 |
| NewYCbCr | *YCbCr | 创建 YCbCr 图像 |
| Pt | Point | 创建点 |
| Rect | Rectangle | 创建矩形 |
解码函数
| 函数 | 返回值 | 用途 |
|---|---|---|
| Decode | (Image, string, error) | 完整解码 |
| DecodeConfig | (Config, string, error) | 只获取配置 |
七、与其他包配合
与 image/color 配合
package main
import (
"image"
"image/color"
)
func main() {
img := image.NewRGBA(image.Rect(0, 0, 100, 100))
// 使用 color 包的颜色
img.Set(50, 50, color.RGBA{255, 0, 0, 255})
img.Set(51, 50, color.NRGBA{0, 255, 0, 255})
// 转换为灰度
gray := color.GrayModel.Convert(img.At(50, 50))
_ = gray
}
与 image/png 配合
package main
import (
"image"
"image/png"
"os"
)
func savePNG(img image.Image, filename string) error {
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
return png.Encode(f, img)
}
与 image/draw 配合
package main
import (
"image"
"image/draw"
)
func composite(src, dst image.Image) {
// 使用 draw 包进行图像合成
draw.Draw(dst, dst.Bounds(), src, image.Point{}, draw.Src)
}
最后更新:2026-04-04
Go 版本:Go 1.23+