Golang的image.ColorModel()函数返回图像的颜色模型。

huangapple go评论83阅读模式
英文:

Golang image ColorModel()

问题

我正在教自己学习Go语言。我决定尝试一些计算机视觉的东西。首先,我要制作一个图像直方图。我试图获取颜色模型,以了解像素的强度范围。当我打印image.ColorModel()时,它给我一个神秘的十六进制输出:

color model: &{0x492f70}

我在文档中找不到任何解释。我原本期望得到一种类似枚举类型的东西,可以映射到颜色模型,比如NRGBA、RGBA等。

这个十六进制表示什么?&{...}中的&和花括号是什么意思?另外,NRGBA中的"N"代表什么?我找不到相关的信息。

英文:

I am teaching myself Go. I decided to try some computer vision stuff. First things first I was going to make an image histogram. I'm trying to get the color model so I know the intensity range of the pixels. When I print image.ColorModel() it gives me a cryptic hexidecimal output:

color model:  &{0x492f70}

I couldn't find any explanation in the docs. I was expecting some sort of enum type thing that would map to a color model like, NRGBA, RGBA, etc.

What does that hexidecimal mean? What does the ampersand curly braces &{...} mean? Also what is the "N" in NRGBA I can't find anything about it.

答案1

得分: 9

为了扩展putu的答案,将返回的颜色模型与image包的“准备好的”模型进行比较,只有在使用其中一个模型时才有效,否则所有比较结果都将为false。而且,列出并与所有可能的模型进行比较非常不方便。

相反,为了找出颜色模型的可交谈形式,我们可以使用这个小技巧:尝试使用图像的颜色模型将任何颜色转换。具体的颜色模型将所有颜色值(实现)转换为图像使用的颜色类型/实现。打印结果颜色的类型将告诉你你要找的是什么。

示例:

col := color.RGBA{} // 这是我们要转换的“任意”颜色
var img image.Image

img = &image.NRGBA{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

img = &image.Gray16{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

img = &image.NYCbCrA{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

img = &image.Paletted{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

输出结果(在Go Playground上尝试):

color.NRGBA
color.Gray16
color.NYCbCrA
<nil>

可以看到,类型为*image.NRGBA的图像使用color.NRGBA来建模颜色,类型为*image.Gray16的图像使用color.Gray16来建模颜色,等等。最后一个例子中,我使用了*image.Paletted,结果为nil,因为图像的调色板为空。

为了快速修复nil调色板,让我们提供一个初始调色板:

img = &image.Paletted{Palette: []color.Color{color.Gray16{}}}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

现在输出结果将是(在Go Playground上尝试):

color.Gray16
英文:

To extend putu's answer, comparing the returned color model to the "prepared" models of the image package only works if one of those models is used, else all comparison will result in false. Also it is quite inconvenient to list and compare to all possible models.

Instead to find out a talkative form of the color model, we may use this little trick: try to convert any color using the color model of the image. A concrete color model converts all color values (implementations) to the color type / implementation used by the image. Printing the type of the resulting color will tell you what you are looking for.

Example:

col := color.RGBA{} // This is the &quot;any&quot; color we convert
var img image.Image

img = &amp;image.NRGBA{}
fmt.Printf(&quot;%T\n&quot;, img.ColorModel().Convert(col))

img = &amp;image.Gray16{}
fmt.Printf(&quot;%T\n&quot;, img.ColorModel().Convert(col))

img = &amp;image.NYCbCrA{}
fmt.Printf(&quot;%T\n&quot;, img.ColorModel().Convert(col))

img = &amp;image.Paletted{}
fmt.Printf(&quot;%T\n&quot;, img.ColorModel().Convert(col))

Output (try it on the Go Playground):

color.NRGBA
color.Gray16
color.NYCbCrA
&lt;nil&gt;

As can be seen, an image of type *image.NRGBA models colors using color.NRGBA, an image of type *image.Gray16 models colors using color.Gray16 etc. As a last example I used *image.Paletted, where the result was nil, because the image's palette was empty.

To quickly fix the nil palette, let's provide an initial palette:

img = &amp;image.Paletted{Palette: []color.Color{color.Gray16{}}}
fmt.Printf(&quot;%T\n&quot;, img.ColorModel().Convert(col))

Now the output will be (try this on the Go Playground):

color.Gray16

答案2

得分: 6

Image 被声明为一个接口,具有以下方法集:

type Image interface {
    ColorModel() color.Model
    Bounds() Rectangle
    At(x, y int) color.Color
}

方法 ColorModel() 返回一个名为 color.Model 的接口,它被声明为:

type Model interface {
    Convert(c Color) Color
}

由于 ColorModel 返回一个接口,你不能使用 * 对其进行解引用。你看到的 &{0x492f70} 是实现 color.Model 接口的底层数据结构,在这种情况下,它是一个指向地址 0x492f70 的指针。通常情况下,ColorModel 的底层数据实现方式并不重要(只要它具有 Convert(c Color) Color 方法即可),但如果你感兴趣的话,几种标准颜色类型的模型都是作为指向未导出结构体的指针实现的,该结构体声明如下:

type modelFunc struct {
    f func(Color) Color
}

当你打印 ColorModel 时,得到的是指向该结构体的指针。尝试使用 fmt.Printf("%+v\n", img.ColorModel()) 打印它,你将看到类似 &{f:0x492f70} 的输出,其中 f 表示上述结构体中的字段名。

文档中,有几种标准颜色类型的模型,例如 color.NRGBAModelcolor.GrayModel 等。如果你想检测图像的颜色模型,可以将其与这些标准模型进行比较,例如:

if img.ColorModel() == color.RGBAModel {
    // 32 位 RGBA 颜色,每个 R、G、B、A 分量需要 8 位
} else if img.ColorModel() == color.GrayModel {
    // 8 位灰度图像
}
//...
英文:

An Image is declared as an interface having the following method sets:

type Image interface {
    ColorModel() color.Model
    Bounds() Rectangle
    At(x, y int) color.Color
}

Method ColorModel() returns an interface named color.Model which is declared as:

type Model interface {
    Convert(c Color) Color
}

Since the ColorModel returns an interface, you can't dereference it using *. What you see as &amp;{0x492f70} is the underlying data structure which implements color.Model interface, and in this case, it is a pointer which points to address 0x492f70. Usually, it doesn't matter how ColorModel's underlying data is implemented (any type is valid as long as it has Convert(c Color) Color method), but if you're curious, the models for several standard color types are implemented as a pointer to unexported struct declared as:

type modelFunc struct {
    f func(Color) Color
}

What you got when you print the ColorModel is a pointer to this struct. Try print it using fmt.Printf(&quot;%+v\n&quot;, img.ColorModel()), you will see an output likes &amp;{f:0x492f70}, in which f denotes the field name in the above struct.

In the documentation, there are several models for the standard color types, e.g. color.NRGBAModel, color.GrayModel, etc. If you want to detect the image's color model, you can compare it to these standard models, e.g.

if img.ColorModel() == color.RGBAModel {
    //32-bit RGBA color, each R,G,B, A component requires 8-bits
} else if img.ColorModel() == color.GrayModel {
    //8-bit grayscale
}
//...

答案3

得分: 0

那个十六进制数是你要打印的变量的内存指针地址。

"&{...}" 这个符号表示参考这个SO帖子

"N" 在 NRGBA 中表示非预乘的32位颜色。请参考文档

英文:

> What does that hexidecimal mean?

Memory pointer address of the variable you're printing.

> What does the ampersand curly braces &{...} mean?

Refer to this SO Post

> what is the "N" in NRGBA

NRGBA represents a non-alpha-premultiplied 32-bit color. Refer to doc.

huangapple
  • 本文由 发表于 2017年7月21日 08:06:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/45226991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定