Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

image - 2D 图像处理

image 包实现了基本的 2D 图像库,提供了图像接口、颜色模型和几何形状的表示。

概述

image 包是 Go 语言图像处理的核心库,定义了图像的基本接口和数据结构。它与 image/colorimage/pngimage/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
}

六、快速参考

图像类型对比

类型位深用途内存
Gray8 位灰度图1 字节/像素
Gray1616 位高精度灰度2 字节/像素
RGBA32 位常规彩色4 字节/像素
RGBA6464 位高精度彩色8 字节/像素
NRGBA32 位PNG 格式4 字节/像素
CMYK32 位印刷4 字节/像素
YCbCr可变视频/JPEG1.5-3 字节/像素
Paletted8 位索引GIF1 字节/像素

几何类型方法

类型方法说明
PointAdd, Sub, In向量运算、包含检查
RectangleDx, Dy, Size尺寸获取
RectangleIntersect, Union集合运算
RectangleOverlaps, In, Empty关系检查

构造函数

函数返回类型说明
NewRGBA*RGBA创建 RGBA 图像
NewRGBA64*RGBA64创建 64 位 RGBA
NewNRGBA*NRGBA创建非预乘 Alpha
NewGray*Gray创建灰度图
NewPaletted*Paletted创建调色板图
NewYCbCr*YCbCr创建 YCbCr 图像
PtPoint创建点
RectRectangle创建矩形

解码函数

函数返回值用途
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+