Go image.Image
界面有三种方法:Bounds
(显然是确定图像大小所必需的),At
(返回每个像素的实际颜色)和ColorModel
。最后一个方法返回color.Model
,它能够将任何模型的颜色转换为该图像使用的表示。
为什么ColorModel
是此界面的一部分? image.Image
类型的消费者如何使用它?如果我有一个图像img
,而我对其底层表示一无所知,那么img.ColorModel()
对我有什么好处?我可以将任何颜色转换为合适的模型,但我不知道我可以使用这种转换颜色;另外两种与图像交互的方式At
和Bounds
,不要将颜色作为参数。
我错过了什么吗?是否有任何标准库函数调用ColorModel
的{{1}}方法,以及用于什么?
答案 0 :(得分:1)
我不确定我是否完全理解你的问题,但我不认为ColorModel()的目的是改变颜色。它只是为了获得颜色模型。
标准库主要在编码图像时使用它,就像在png包中一样:
switch m.ColorModel() {
case color.GrayModel:
e.cb = cbG8
case color.Gray16Model:
e.cb = cbG16
case color.RGBAModel, color.NRGBAModel, color.AlphaModel:
if opaque(m) {
e.cb = cbTC8
} else {
e.cb = cbTCA8
}
default:
if opaque(m) {
e.cb = cbTC16
} else {
e.cb = cbTCA16
}
}
可以在jpeg / writer中找到关于它的预期用途的另一个暗示:
// TODO(wathiede): switch on m.ColorModel() instead of type.
答案 1 :(得分:1)
扩大接受的答案:
虽然color.Model
能够将颜色转换为不同的颜色类型,但如the docs中所述:
界面
ColorModel
描述了图像的颜色模型。
即。不是像素的颜色模型。它看起来很相似,但后者暗示图像可能包含具有不同颜色模型的像素。
注意image
表示均匀颜色的矩形网格,即所有像素具有相同的颜色模型。理解image
的颜色模型后,将image
投射到特定的具体图像类型会更好,更有效,然后直接在该特定图像上工作。以下片段说明了这个想法:
switch img.ColorModel() {
case color.RGBAModel:
// Try to cast to RGBA first
m, ok := img.(*image.RGBA)
if !ok {
//not an RGBA image, do generic/custom processing,
//e.g. using interface exposed by image.Image
return
}
//Direct pixel access for performance
for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
yp := (y - m.Rect.Min.Y) * m.Stride
for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
rgba := m.Pix[yp+(x-m.Rect.Min.X)*4:] //[]byte{r, g, b, a}
//get rgba component
r, g, b, a := rgba[0], rgba[1], rgba[2], rgba[3]
//set r channel to RED
rgba[0] = 255
//...
}
}
}
与以下代码相比,更有效
// Less efficient image processing
// a type-switch on the color returned by the `At` method
b := img.Bounds()
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; x < b.Max.X; x++ {
col := img.At(x, y)
switch col := col.(type) {
case color.RGBA:
//do something with pixel
}
}
}