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/color - 颜色模型

image/color 包实现了基本的颜色类型和颜色模型,为图像处理提供颜色表示和转换功能。

概述

image/color 包是 Go 语言图像库的颜色基础包,定义了颜色接口、颜色模型接口以及各种具体的颜色类型。它与 image 包配合使用,为图像处理提供完整的颜色支持。

包导入

import "image/color"

基本使用

// 1. 创建颜色
c := color.RGBA{255, 0, 0, 255}  // 红色

// 2. 获取 RGBA 值
r, g, b, a := c.RGBA()

// 3. 颜色模型转换
gray := color.GrayModel.Convert(c)

// 4. 使用调色板
palette := color.Palette{c, color.Black}

典型示例

示例 1:创建基本颜色

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // RGB 颜色
    red := color.RGBA{255, 0, 0, 255}
    green := color.RGBA{0, 255, 0, 255}
    blue := color.RGBA{0, 0, 255, 255}
    
    fmt.Printf("红色:%v\n", red)
    fmt.Printf("绿色:%v\n", green)
    fmt.Printf("蓝色:%v\n", blue)
    
    // 获取 RGBA 值(16 位)
    r, g, b, a := red.RGBA()
    fmt.Printf("红色 RGBA: R=%04x G=%04x B=%04x A=%04x\n", r, g, b, a)
}

运行

$ go run main.go
红色:{255 0 0 255}
绿色:{0 255 0 255}
蓝色:{0 0 255 255}
红色 RGBA: R=ffff G=0000 B=0000 A=ffff

示例 2:颜色模型转换

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 原始彩色
    c := color.RGBA{255, 128, 64, 255}
    
    // 转换为灰度
    gray := color.GrayModel.Convert(c).(color.Gray)
    fmt.Printf("原始:%v\n", c)
    fmt.Printf("灰度:%v\n", gray)
    
    // 转换为 Alpha
    alpha := color.AlphaModel.Convert(c).(color.Alpha)
    fmt.Printf("Alpha: %v\n", alpha)
    
    // 转换为 CMYK
    cmyk := color.CMYKModel.Convert(c).(color.CMYK)
    fmt.Printf("CMYK: %v\n", cmyk)
}

运行

$ go run main.go
原始:{255 128 64 255}
灰度:{154}
Alpha: {255}
CMYK: {0 128 191 0}

示例 3:使用调色板

package main

import (
    "fmt"
    "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},
        color.RGBA{0, 0, 0, 255},
    }
    
    // 转换颜色到调色板
    c := color.RGBA{250, 10, 10, 255}  // 接近红色
    converted := palette.Convert(c)
    
    fmt.Printf("原始:%v\n", c)
    fmt.Printf("转换后:%v\n", converted)
    fmt.Printf("调色板索引:%d\n", palette.Index(c))
}

运行

$ go run main.go
原始:{250 10 10 255}
转换后:{255 0 0 255}
调色板索引:0

一、核心接口(按字母顺序)

Color 接口

Color

定义

type Color interface {
    RGBA() (r, g, b, a uint32)
}

说明

  • 颜色的基本接口
  • 所有颜色类型都实现此接口
  • 返回 alpha 预乘的 16 位颜色值

方法

  • RGBA() (r, g, b, a uint32) - 返回 RGBA 值
    • 每个值范围 [0, 0xFFFF]
    • alpha 预乘格式
    • uint32 类型防止乘法溢出

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 使用接口
    var c color.Color = color.RGBA{255, 128, 64, 255}
    
    r, g, b, a := c.RGBA()
    fmt.Printf("R=%04x G=%04x B=%04x A=%04x\n", r, g, b, a)
    
    // 转换为具体类型
    if rgba, ok := c.(color.RGBA); ok {
        fmt.Printf("RGBA: R=%d G=%d B=%d A=%d\n", rgba.R, rgba.G, rgba.B, rgba.A)
    }
}

运行

$ go run main.go
R=ffff G=8080 B=4040 A=ffff
RGBA: R=255 G=128 B=64 A=255

Model 接口

Model

定义

type Model interface {
    Convert(c Color) Color
}

说明

  • 颜色模型接口
  • 将颜色转换为特定颜色空间
  • 转换可能有损

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 原始颜色
    c := color.RGBA{255, 128, 64, 255}
    
    // 使用不同模型转换
    gray := color.GrayModel.Convert(c)
    alpha := color.AlphaModel.Convert(c)
    cmyk := color.CMYKModel.Convert(c)
    
    fmt.Printf("原始:%v\n", c)
    fmt.Printf("灰度:%v\n", gray)
    fmt.Printf("Alpha: %v\n", alpha)
    fmt.Printf("CMYK: %v\n", cmyk)
}

运行

$ go run main.go
原始:{255 128 64 255}
灰度:{154}
Alpha: {255}
CMYK: {0 128 191 0}

二、颜色类型(按字母顺序)

Alpha 类型

Alpha

定义

type Alpha struct {
    A uint8
}

说明

  • 8 位 Alpha 通道颜色
  • 范围 [0, 255]
  • 用于透明度表示

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 Alpha 颜色
    a := color.Alpha{128}
    
    // 获取 RGBA 值
    r, g, b, alpha := a.RGBA()
    fmt.Printf("Alpha: A=%d\n", a.A)
    fmt.Printf("RGBA: R=%04x G=%04x B=%04x A=%04x\n", r, g, b, alpha)
    
    // 完全透明
    transparent := color.Alpha{0}
    fmt.Printf("完全透明:%v\n", transparent)
    
    // 完全不透明
    opaque := color.Alpha{255}
    fmt.Printf("完全不透明:%v\n", opaque)
}

运行

$ go run main.go
Alpha: A=128
RGBA: R=0000 G=0000 B=0000 A=8080
完全透明:{0}
完全不透明:{255}

Alpha16 类型

Alpha16

定义

type Alpha16 struct {
    A uint16
}

说明

  • 16 位 Alpha 通道颜色
  • 范围 [0, 0xFFFF]
  • 高精度透明度

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 Alpha16 颜色
    a := color.Alpha16{0x8000}
    
    r, g, b, alpha := a.RGBA()
    fmt.Printf("Alpha16: A=%04x\n", a.A)
    fmt.Printf("RGBA: A=%04x\n", alpha)
    
    // 完全透明
    transparent := color.Alpha16{0x0000}
    fmt.Printf("完全透明:%04x\n", transparent.A)
    
    // 完全不透明
    opaque := color.Alpha16{0xFFFF}
    fmt.Printf("完全不透明:%04x\n", opaque.A)
}

运行

$ go run main.go
Alpha16: A=8000
RGBA: A=8000
完全透明:0000
完全不透明:ffff

CMYK 类型

CMYK

定义

type CMYK struct {
    C, M, Y, K uint8
}

说明

  • CMYK 四分色颜色
  • Cyan(青)、Magenta(品红)、Yellow(黄)、Key(黑)
  • 用于印刷
  • 每个分量范围 [0, 255]

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口
  • CMYK() (c, m, y, k uint32) - 返回 CMYK 值(16 位)

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 CMYK 颜色(纯青色)
    cyan := color.CMYK{255, 0, 0, 0}
    magenta := color.CMYK{0, 255, 0, 0}
    yellow := color.CMYK{0, 0, 255, 0}
    black := color.CMYK{0, 0, 0, 255}
    
    fmt.Printf("青色:%v\n", cyan)
    fmt.Printf("品红:%v\n", magenta)
    fmt.Printf("黄色:%v\n", yellow)
    fmt.Printf("黑色:%v\n", black)
    
    // 转换为 RGBA
    r, g, b, a := cyan.RGBA()
    fmt.Printf("青色转 RGBA: R=%02x G=%02x B=%02x A=%02x\n", r>>8, g>>8, b>>8, a>>8)
}

运行

$ go run main.go
青色:{255 0 0 0}
品红:{0 255 0 0}
黄色:{0 0 255 0}
黑色:{0 0 0 255}
青色转 RGBA: R=00 G=ff B=ff A=ff

Gray 类型

Gray

定义

type Gray struct {
    Y uint8
}

说明

  • 8 位灰度颜色
  • 范围 [0, 255]
  • 0=黑,255=白

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建灰度颜色
    black := color.Gray{0}
    gray := color.Gray{128}
    white := color.Gray{255}
    
    fmt.Printf("黑色:%v\n", black)
    fmt.Printf("灰色:%v\n", gray)
    fmt.Printf("白色:%v\n", white)
    
    // 转换为 RGBA
    r, g, b, a := gray.RGBA()
    fmt.Printf("灰色 RGBA: R=%02x G=%02x B=%02x A=%02x\n", r>>8, g>>8, b>>8, a>>8)
}

运行

$ go run main.go
黑色:{0}
灰色:{128}
白色:{255}
灰色 RGBA: R=80 G=80 B=80 A=ff

Gray16 类型

Gray16

定义

type Gray16 struct {
    Y uint16
}

说明

  • 16 位灰度颜色
  • 范围 [0, 0xFFFF]
  • 高精度灰度

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 Gray16 颜色
    black := color.Gray16{0x0000}
    gray := color.Gray16{0x8000}
    white := color.Gray16{0xFFFF}
    
    fmt.Printf("黑色:%04x\n", black.Y)
    fmt.Printf("灰色:%04x\n", gray.Y)
    fmt.Printf("白色:%04x\n", white.Y)
}

运行

$ go run main.go
黑色:0000
灰色:8000
白色:ffff

NRGBA 类型

NRGBA

定义

type NRGBA struct {
    R, G, B, A uint8
}

说明

  • 非预乘 Alpha 的 RGBA 颜色
  • 颜色分量与 Alpha 独立
  • PNG 格式使用此格式
  • 每个分量范围 [0, 255]

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口(返回 alpha 预乘值)

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 NRGBA 颜色(半透明红色)
    c := color.NRGBA{255, 0, 0, 128}
    
    fmt.Printf("NRGBA: R=%d G=%d B=%d A=%d\n", c.R, c.G, c.B, c.A)
    
    // 转换为 RGBA(alpha 预乘)
    r, g, b, a := c.RGBA()
    fmt.Printf("RGBA: R=%02x G=%02x B=%02x A=%02x\n", r>>8, g>>8, b>>8, a>>8)
    
    // 完全透明
    transparent := color.NRGBA{255, 0, 0, 0}
    fmt.Printf("完全透明:%v\n", transparent)
}

运行

$ go run main.go
NRGBA: R=255 G=0 B=0 A=128
RGBA: R=80 G=00 B=00 A=80
完全透明:{255 0 0 0}

NRGBA64 类型

NRGBA64

定义

type NRGBA64 struct {
    R, G, B, A uint16
}

说明

  • 64 位非预乘 Alpha 颜色
  • 每个分量 16 位(大端格式)
  • 高精度颜色

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 NRGBA64 颜色
    c := color.NRGBA64{
        R: 0xFFFF,
        G: 0x8000,
        B: 0x0000,
        A: 0xFFFF,
    }
    
    fmt.Printf("NRGBA64: R=%04x G=%04x B=%04x A=%04x\n", c.R, c.G, c.B, c.A)
    
    r, g, b, a := c.RGBA()
    fmt.Printf("RGBA: R=%04x G=%04x B=%04x A=%04x\n", r, g, b, a)
}

运行

$ go run main.go
NRGBA64: R=ffff G=8000 B=0000 A=ffff
RGBA: R=ffff G=8000 B=0000 A=ffff

NYCbCrA 类型

NYCbCrA

定义

type NYCbCrA struct {
    Y, Cb, Cr, A uint8
}

说明

  • YCbCr 颜色 + Alpha 通道
  • 用于视频处理
  • Y=亮度,Cb/Cr=色度

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 NYCbCrA 颜色
    c := color.NYCbCrA{
        Y:  128,
        Cb: 128,
        Cr: 128,
        A:  255,
    }
    
    fmt.Printf("NYCbCrA: Y=%d Cb=%d Cr=%d A=%d\n", c.Y, c.Cb, c.Cr, c.A)
    
    r, g, b, a := c.RGBA()
    fmt.Printf("RGBA: R=%02x G=%02x B=%02x A=%02x\n", r>>8, g>>8, b>>8, a>>8)
}

运行

$ go run main.go
NYCbCrA: Y=128 Cb=128 Cr=128 A=255
RGBA: R=80 G=80 B=80 A=ff

RGBA 类型

RGBA

定义

type RGBA struct {
    R, G, B, A uint8
}

说明

  • 最常用的颜色类型
  • 8 位 RGBA 颜色
  • Alpha 预乘格式
  • 每个分量范围 [0, 255]

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 RGBA 颜色
    red := color.RGBA{255, 0, 0, 255}
    green := color.RGBA{0, 255, 0, 255}
    blue := color.RGBA{0, 0, 255, 255}
    transparent := color.RGBA{0, 0, 0, 0}
    
    fmt.Printf("红色:%v\n", red)
    fmt.Printf("绿色:%v\n", green)
    fmt.Printf("蓝色:%v\n", blue)
    fmt.Printf("透明:%v\n", transparent)
    
    // 获取 16 位 RGBA 值
    r, g, b, a := red.RGBA()
    fmt.Printf("红色 16 位:R=%04x G=%04x B=%04x A=%04x\n", r, g, b, a)
    
    // 半透明红色
    semiTransparent := color.RGBA{255, 0, 0, 128}
    fmt.Printf("半透明红色:%v\n", semiTransparent)
}

运行

$ go run main.go
红色:{255 0 0 255}
绿色:{0 255 0 255}
蓝色:{0 0 255 255}
透明:{0 0 0 0}
红色 16 位:R=ffff G=0000 B=0000 A=ffff
半透明红色:{255 0 0 128}

RGBA64 类型

RGBA64

定义

type RGBA64 struct {
    R, G, B, A uint16
}

说明

  • 64 位 RGBA 颜色
  • 每个分量 16 位(大端格式)
  • 高精度颜色

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 RGBA64 颜色
    red := color.RGBA64{
        R: 0xFFFF,
        G: 0x0000,
        B: 0x0000,
        A: 0xFFFF,
    }
    
    fmt.Printf("红色:%04x %04x %04x %04x\n", red.R, red.G, red.B, red.A)
    
    // 半透明(50%)
    semiTransparent := color.RGBA64{
        R: 0xFFFF,
        G: 0x0000,
        B: 0x0000,
        A: 0x8000,
    }
    fmt.Printf("半透明:%04x %04x %04x %04x\n", 
        semiTransparent.R, semiTransparent.G, semiTransparent.B, semiTransparent.A)
}

运行

$ go run main.go
红色:ffff 0000 0000 ffff
半透明:ffff 0000 0000 8000

YCbCr 类型

YCbCr

定义

type YCbCr struct {
    Y, Cb, Cr uint8
}

说明

  • YCbCr 颜色空间
  • Y=亮度,Cb=蓝色差,Cr=红色差
  • 用于视频和 JPEG 压缩

方法

  • RGBA() (r, g, b, a uint32) - 实现 Color 接口

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 YCbCr 颜色
    // 灰色(Cb=Cr=128)
    gray := color.YCbCr{128, 128, 128}
    
    // 红色
    red := color.YCbCr{76, 84, 255}
    
    fmt.Printf("灰色:Y=%d Cb=%d Cr=%d\n", gray.Y, gray.Cb, gray.Cr)
    fmt.Printf("红色:Y=%d Cb=%d Cr=%d\n", red.Y, red.Cb, red.Cr)
    
    r, g, b, a := red.RGBA()
    fmt.Printf("红色 RGBA: R=%02x G=%02x B=%02x A=%02x\n", r>>8, g>>8, b>>8, a>>8)
}

运行

$ go run main.go
灰色:Y=128 Cb=128 Cr=128
红色:Y=76 Cb=84 Cr=255
红色 RGBA: R=ff G=00 B=00 A=ff

三、调色板类型

Palette 类型

Palette

定义

type Palette []Color

说明

  • 颜色调色板
  • 有限的颜色集合
  • 用于调色板图像

方法

  • Convert(c Color) Color - 转换颜色到调色板
  • Index(c Color) int - 获取颜色在调色板中的索引

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    // 创建 8 色调色板
    palette := color.Palette{
        color.RGBA{0, 0, 0, 255},      // 黑
        color.RGBA{128, 128, 128, 255}, // 灰
        color.RGBA{255, 255, 255, 255}, // 白
        color.RGBA{255, 0, 0, 255},     // 红
        color.RGBA{0, 255, 0, 255},     // 绿
        color.RGBA{0, 0, 255, 255},     // 蓝
        color.RGBA{255, 255, 0, 255},   // 黄
        color.RGBA{255, 0, 255, 255},   // 品红
    }
    
    // 测试颜色匹配
    testColors := []color.Color{
        color.RGBA{0, 0, 0, 255},       // 黑
        color.RGBA{250, 10, 10, 255},   // 接近红
        color.RGBA{10, 250, 10, 255},   // 接近绿
        color.RGBA{100, 100, 100, 255}, // 接近灰
    }
    
    for _, c := range testColors {
        idx := palette.Index(c)
        fmt.Printf("颜色:%v -> 索引:%d -> 匹配:%v\n", c, idx, palette[idx])
    }
}

运行

$ go run main.go
颜色:{0 0 0 255} -> 索引:0 -> 匹配:{0 0 0 255}
颜色:{250 10 10 255} -> 索引:3 -> 匹配:{255 0 0 255}
颜色:{10 250 10 255} -> 索引:4 -> 匹配:{0 255 0 255}
颜色:{100 100 100 255} -> 索引:1 -> 匹配:{128 128 128 255}

四、预定义颜色模型

AlphaModel

AlphaModel

定义

var AlphaModel Model

说明

  • 预定义的 Alpha 颜色模型
  • 将颜色转换为 Alpha

示例

gray := color.AlphaModel.Convert(c).(color.Alpha)

Alpha16Model

Alpha16Model

定义

var Alpha16Model Model

说明

  • 预定义的 16 位 Alpha 颜色模型

CMYKModel

CMYKModel

定义

var CMYKModel Model

说明

  • 预定义的 CMYK 颜色模型
  • 将颜色转换为 CMYK

GrayModel

GrayModel

定义

var GrayModel Model

说明

  • 预定义的灰度颜色模型
  • 将颜色转换为灰度

示例

package main

import (
    "fmt"
    "image/color"
)

func main() {
    colors := []color.Color{
        color.RGBA{255, 0, 0, 255},
        color.RGBA{0, 255, 0, 255},
        color.RGBA{0, 0, 255, 255},
    }
    
    for _, c := range colors {
        gray := color.GrayModel.Convert(c).(color.Gray)
        fmt.Printf("%v -> 灰度:%v\n", c, gray)
    }
}

运行

$ go run main.go
{255 0 0 255} -> 灰度:{76}
{0 255 0 255} -> 灰度:{150}
{0 0 255 255} -> 灰度:{29}

Gray16Model

Gray16Model

定义

var Gray16Model Model

说明

  • 预定义的 16 位灰度颜色模型

NRGBAModel

NRGBAModel

定义

var NRGBAModel Model

说明

  • 预定义的 NRGBA 颜色模型

NRGBA64Model

NRGBA64Model

定义

var NRGBA64Model Model

说明

  • 预定义的 64 位 NRGBA 颜色模型

RGBAModel

RGBAModel

定义

var RGBAModel Model

说明

  • 预定义的 RGBA 颜色模型
  • 最常用的颜色模型

示例

rgba := color.RGBAModel.Convert(c).(color.RGBA)

RGBA64Model

RGBA64Model

定义

var RGBA64Model Model

说明

  • 预定义的 64 位 RGBA 颜色模型

NYCbCrAModel

NYCbCrAModel

定义

var NYCbCrAModel Model

说明

  • 预定义的 NYCbCrA 颜色模型

YCbCrModel

YCbCrModel

定义

var YCbCrModel Model

说明

  • 预定义的 YCbCr 颜色模型
  • 将颜色转换为 YCbCr

五、使用场景

场景 1:图像灰度化

package main

import (
    "fmt"
    "image"
    "image/color"
)

func toGray(img image.Image) *image.Gray {
    bounds := img.Bounds()
    gray := image.NewGray(bounds)
    
    for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
        for x := bounds.Min.X; x < bounds.Max.X; x++ {
            c := img.At(x, y)
            gray.Set(x, y, color.GrayModel.Convert(c))
        }
    }
    
    return gray
}

func main() {
    // 创建测试图像
    img := image.NewRGBA(image.Rect(0, 0, 100, 100))
    img.Set(50, 50, color.RGBA{255, 128, 64, 255})
    
    // 转换为灰度
    gray := toGray(img)
    fmt.Printf("原始:%v\n", img.At(50, 50))
    fmt.Printf("灰度:%v\n", gray.At(50, 50))
}

场景 2:颜色量化

package main

import (
    "fmt"
    "image/color"
)

// 创建 Web 安全调色板(216 色)
func createWebSafePalette() color.Palette {
    var palette color.Palette
    for r := 0; r < 6; r++ {
        for g := 0; g < 6; g++ {
            for b := 0; b < 6; b++ {
                palette = append(palette, color.RGBA{
                    R: uint8(r * 51),
                    G: uint8(g * 51),
                    B: uint8(b * 51),
                    A: 255,
                })
            }
        }
    }
    return palette
}

func main() {
    palette := createWebSafePalette()
    fmt.Printf("Web 安全调色板:%d 色\n", len(palette))
    
    // 测试颜色匹配
    c := color.RGBA{255, 100, 50, 255}
    idx := palette.Index(c)
    fmt.Printf("颜色:%v -> 索引:%d -> 匹配:%v\n", c, idx, palette[idx])
}

运行

$ go run main.go
Web 安全调色板:216 色
颜色:{255 100 50 255} -> 索引:125 -> 匹配:{255 102 51 255}

场景 3:透明度混合

package main

import (
    "fmt"
    "image/color"
)

// 混合两个颜色(alpha 混合)
func blend(c1, c2 color.RGBA) color.RGBA {
    a1 := float64(c1.A) / 255.0
    a2 := float64(c2.A) / 255.0
    
    // 计算混合后的 alpha
    outA := a1 + a2*(1-a1)
    
    if outA == 0 {
        return color.RGBA{}
    }
    
    // 计算混合后的 RGB
    outR := uint8((float64(c1.R)*a1 + float64(c2.R)*a2*(1-a1)) / outA)
    outG := uint8((float64(c1.G)*a1 + float64(c2.G)*a2*(1-a1)) / outA)
    outB := uint8((float64(c1.B)*a1 + float64(c2.B)*a2*(1-a1)) / outA)
    
    return color.RGBA{outR, outG, outB, uint8(outA * 255)}
}

func main() {
    // 红色(不透明)
    red := color.RGBA{255, 0, 0, 255}
    
    // 蓝色(半透明)
    blue := color.RGBA{0, 0, 255, 128}
    
    result := blend(red, blue)
    fmt.Printf("红色:%v\n", red)
    fmt.Printf("蓝色:%v\n", blue)
    fmt.Printf("混合:%v\n", result)
}

运行

$ go run main.go
红色:{255 0 0 255}
蓝色:{0 0 255 128}
混合:{170 0 85 255}

六、快速参考

颜色类型对比

类型位深分量用途
Alpha8 位A透明度蒙版
Alpha1616 位A高精度透明
Gray8 位Y灰度图像
Gray1616 位Y高精度灰度
RGBA32 位R,G,B,A常规彩色
RGBA6464 位R,G,B,A高精度彩色
NRGBA32 位R,G,B,APNG 格式
NRGBA6464 位R,G,B,A高精度 PNG
CMYK32 位C,M,Y,K印刷
YCbCr24 位Y,Cb,Cr视频
NYCbCrA32 位Y,Cb,Cr,A视频 + 透明

颜色模型

模型转换目标说明
RGBAModelRGBA标准 RGBA
RGBA64ModelRGBA6464 位 RGBA
NRGBAModelNRGBA非预乘 Alpha
GrayModelGray灰度
Gray16ModelGray1616 位灰度
CMYKModelCMYK印刷四分色
YCbCrModelYCbCr视频颜色空间

RGBA() 返回值

类型返回值范围说明
RGBA[0, 0xFFFF]alpha 预乘
NRGBA[0, 0xFFFF]转换为 alpha 预乘
Gray[0, 0xFFFF]R=G=B=Y*0x101
CMYK[0, 0xFFFF]从 CMYK 转换

预定义模型变量

变量类型用途
RGBAModelModelRGBA 转换
GrayModelModel灰度转换
CMYKModelModelCMYK 转换
AlphaModelModelAlpha 转换

七、与其他包配合

与 image 包配合

package main

import (
    "image"
    "image/color"
)

func main() {
    // 创建图像
    img := image.NewRGBA(image.Rect(0, 0, 100, 100))
    
    // 设置颜色
    img.Set(50, 50, color.RGBA{255, 0, 0, 255})
    
    // 获取颜色
    c := img.At(50, 50)
    
    // 转换为灰度
    gray := color.GrayModel.Convert(c)
    img.Set(51, 50, gray)
}

与 image/draw 包配合

package main

import (
    "image"
    "image/color"
    "image/draw"
)

func main() {
    // 创建目标图像
    dst := image.NewRGBA(image.Rect(0, 0, 100, 100))
    
    // 用纯色填充
    draw.Draw(dst, dst.Bounds(), &image.Uniform{color.RGBA{255, 0, 0, 255}}, 
        image.Point{}, draw.Src)
}

与 image/png 包配合

package main

import (
    "image"
    "image/color"
    "image/png"
    "os"
)

func main() {
    // 创建图像
    img := image.NewRGBA(image.Rect(0, 0, 100, 100))
    
    // 绘制渐变
    for y := 0; y < 100; y++ {
        for x := 0; x < 100; x++ {
            img.Set(x, y, color.RGBA{
                R: uint8(x * 255 / 100),
                G: uint8(y * 255 / 100),
                B: 128,
                A: 255,
            })
        }
    }
    
    // 保存为 PNG
    f, _ := os.Create("gradient.png")
    defer f.Close()
    png.Encode(f, img)
}

八、注意事项

1. Alpha 预乘

// RGBA 类型使用 alpha 预乘
// 实际存储的 RGB 值已经乘以 alpha

c := color.RGBA{255, 0, 0, 128}  // 半透明红色
r, g, b, a := c.RGBA()
// r = 0x8080 (不是 0xffff)

2. NRGBA vs RGBA

// NRGBA:颜色分量独立于 alpha
nrgba := color.NRGBA{255, 0, 0, 128}

// RGBA:alpha 预乘格式
rgba := color.RGBA{255, 0, 0, 128}

// 转换为 RGBA() 时,NRGBA 会进行 alpha 预乘

3. 16 位颜色范围

// 16 位颜色范围是 [0, 0xFFFF]
// 不是 [0, 255]

c64 := color.RGBA64{
    R: 0xFFFF,  // 最大红色
    G: 0x8000,  // 50% 绿色
    B: 0x0000,  // 无蓝色
    A: 0xFFFF,  // 不透明
}

4. 颜色转换可能有损

// 从彩色转换为灰度会丢失颜色信息
c := color.RGBA{255, 0, 0, 255}
gray := color.GrayModel.Convert(c).(color.Gray)
// gray.Y = 76(无法还原为原始红色)

5. Palette.Index 使用欧几里得距离

// Index 方法计算颜色之间的欧几里得距离
// 返回最接近的颜色索引

palette := color.Palette{color.Black, color.White}
idx := palette.Index(color.RGBA{100, 100, 100, 255})
// 可能返回 0 或 1,取决于哪个更接近

最后更新:2026-04-04
Go 版本:Go 1.23+