去图像处理

Rag*_*aer 2 image colors go rgba

我需要加载图像并搜索颜色并替换它们。例如,在图像上,我需要搜索所有红色像素并将其转换为紫色。

我正在执行以下操作(img是有效的.png图像):

func colorize(img image.Image) {
    b := image.NewRGBA(img.Bounds())
    draw.Draw(b, b.Bounds(), img, image.ZP, draw.Src)
    for x := 0; x < b.Bounds().Dx(); x++ {
        for y := 0; y < b.Bounds().Dy(); y++ {
            log.Println(b.At(x, y).RGBA())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

事情是img.At().RGBA()似乎没有返回正确的R,G,B,A码?例如,我得到的数字大于255。

因此,如何读取所有图像像素,同时又能知道它们的x和y位置?

icz*_*cza 6

img.At().RGBA()Color.RGBA()。引用其文档:

// RGBA returns the alpha-premultiplied red, green, blue and alpha values
// for the color. Each value ranges within [0, 0xffff], but is represented
// by a uint32 so that multiplying by a blend factor up to 0xffff will not
// overflow.
//
// An alpha-premultiplied color component c has been scaled by alpha (a),
// so has valid values 0 <= c <= a.
Run Code Online (Sandbox Code Playgroud)

返回的分量RGBA()在range 0..0xffff而不是范围内,0..0xff并且它们也是alpha预乘的。

手动解码

取回该0..255范围内的红色,绿色,蓝色分量的一种方法是,例如,向右移动8:

r, g, b, a := b.At(x, y).RGBA()
r, g, b, a = r>>8, g>>8, b>>8, a>>8
log.Println(r, g, b) // Now in range 0..255
Run Code Online (Sandbox Code Playgroud)

转换为 color.RGBA

另一种方法是将颜色转换color.RGBA为结构,其中包含简单明了的组件:

type RGBA struct {
        R, G, B, A uint8
}
Run Code Online (Sandbox Code Playgroud)

由于您使用的image.NewRGBA()是返回类型为image的图像image.RGBA,因此该Image.At()方法返回的颜色将为动态类型color.RGBA,因此您可以简单地使用类型断言

rgbacol := b.At(x, y).(color.RGBA)
log.Println(rgbacol.R, rgbacol.G, rgbacol.B, rgbacol.A)
Run Code Online (Sandbox Code Playgroud)

通常(如果图像不是类型的image.RGBA),Image.At()则可能是也可能不是具体的类型color.RGBA

因此,通常情况下,您需要将颜色转换为type的值color.RGBA。颜色模型之间的转换由建模color.Model,并且image/color程序包具有预定义的转换器。您需要的是color.RGBAModelcolor.RGBAModel.Convert()将返回color.Color其动态类型肯定为的值color.RGBA

使用示例color.RGBAModel

var c color.Color
c = color.Gray{160}

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

fmt.Println(rgbacol.R, rgbacol.G, rgbacol.B, rgbacol.A)
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上尝试):

160 160 160 255
Run Code Online (Sandbox Code Playgroud)

因此,在循环中执行以下操作:

rgbacol := color.RGBAModel.Convert(b.At(x, y).(color.RGBA)
// rgbacol is a struct of type color.RGBA, components are in range 0..255
Run Code Online (Sandbox Code Playgroud)

注意:

上述解决方案仍然可以为您提供Alpha预乘分量。如果您要撤消Alpha预乘,则可以使用color.NRGBAModel转换器(而不是color.RGBAModel)。