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}
六、快速参考
颜色类型对比
| 类型 | 位深 | 分量 | 用途 |
|---|---|---|---|
| Alpha | 8 位 | A | 透明度蒙版 |
| Alpha16 | 16 位 | A | 高精度透明 |
| Gray | 8 位 | Y | 灰度图像 |
| Gray16 | 16 位 | Y | 高精度灰度 |
| RGBA | 32 位 | R,G,B,A | 常规彩色 |
| RGBA64 | 64 位 | R,G,B,A | 高精度彩色 |
| NRGBA | 32 位 | R,G,B,A | PNG 格式 |
| NRGBA64 | 64 位 | R,G,B,A | 高精度 PNG |
| CMYK | 32 位 | C,M,Y,K | 印刷 |
| YCbCr | 24 位 | Y,Cb,Cr | 视频 |
| NYCbCrA | 32 位 | Y,Cb,Cr,A | 视频 + 透明 |
颜色模型
| 模型 | 转换目标 | 说明 |
|---|---|---|
| RGBAModel | RGBA | 标准 RGBA |
| RGBA64Model | RGBA64 | 64 位 RGBA |
| NRGBAModel | NRGBA | 非预乘 Alpha |
| GrayModel | Gray | 灰度 |
| Gray16Model | Gray16 | 16 位灰度 |
| CMYKModel | CMYK | 印刷四分色 |
| YCbCrModel | YCbCr | 视频颜色空间 |
RGBA() 返回值
| 类型 | 返回值范围 | 说明 |
|---|---|---|
| RGBA | [0, 0xFFFF] | alpha 预乘 |
| NRGBA | [0, 0xFFFF] | 转换为 alpha 预乘 |
| Gray | [0, 0xFFFF] | R=G=B=Y*0x101 |
| CMYK | [0, 0xFFFF] | 从 CMYK 转换 |
预定义模型变量
| 变量 | 类型 | 用途 |
|---|---|---|
| RGBAModel | Model | RGBA 转换 |
| GrayModel | Model | 灰度转换 |
| CMYKModel | Model | CMYK 转换 |
| AlphaModel | Model | Alpha 转换 |
七、与其他包配合
与 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+