Reputation: 2124
Go's image.Image
interface has three methods: Bounds
(clearly necessary for determining the size of an image), At
(which returns the actual color at each pixel), and ColorModel
. This last method returns a color.Model
, which is capable of converting a color from any model into the representation that this image uses.
Why is ColorModel
a part of this interface? How is it used by consumers of the image.Image
type? If I have an image img
, and I know nothing about its underlying representation, what good does img.ColorModel()
do me? I can convert any color into the proper model, but I don't see what I can use this converted color for; the other two ways of interacting with an image, At
and Bounds
, do not take colors as arguments.
Am I missing something? Do any standard library functions call the ColorModel
method of an image.Image
, and what for?
Upvotes: 2
Views: 763
Reputation: 6444
To extend the accepted answer:
Although the color.Model
is capable of converting a color to a different color type, as said in the docs:
Interface
ColorModel
describes the image's color model.
i.e. it's not the pixel's color model. It looks similar, but the latter implies that an image may contain pixel(s) with a different color model.
Note that an image
represents a rectangular grid of homogeneous colors, i.e. all pixels have the same color model. Once you understand the color model of an image
, it's better and more efficient to cast the image
to a particular concrete image type, then work directly on that particular image. The following snippet illustrates the idea:
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
//...
}
}
}
is more efficient compared to the following code
// 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
}
}
}
Upvotes: 1
Reputation: 121
I'm not sure if I understand your question entirely, but I do not think the purpose of ColorModel() is to change the color. It is only to get the color model.
The standard library uses it mostly when encoding images, like in the png package:
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
}
}
Another hint on it's intended use can be found in the jpeg/writer:
// TODO(wathiede): switch on m.ColorModel() instead of type.
Upvotes: 3