去图像处理

Go image manipulation

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

我正在执行以下操作(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())
        }
    }
}

问题是 img.At().RGBA() 似乎 return 没有正确的 R、G、B、A 代码?例如,我得到的数字大于 255。

那么我应该如何读取所有图像像素,同时能够知道它们的 x 和 y 位置?

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.

return 由 RGBA() 编辑的组件在 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

正在转换为 color.RGBA

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

type RGBA struct {
        R, G, B, A uint8
}

因为您正在使用 image.NewRGBA() which returns an image of type image.RGBA, the colors returned by the Image.At() method will be of dynamic type color.RGBA, so you can simply use a type assertion:

rgbacol := b.At(x, y).(color.RGBA)
log.Println(rgbacol.R, rgbacol.G, rgbacol.B, rgbacol.A)

一般来说(如果图像不是 image.RGBA 类型),Image.At() 可能是也可能不是具体类型 color.RGBA

所以一般情况下需要将颜色转换为color.RGBA类型的值。颜色模型之间的转换由 color.Model 建模,并且 image/color 包具有预定义的转换器。你需要的是color.RGBAModelcolor.RGBAModel.Convert() 将 return 一个 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)

输出(在 Go Playground 上尝试):

160 160 160 255

所以在你的循环中做:

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

注:

以上解决方案仍会返回 alpha 预乘分量。如果你想撤销 alpha 预乘,你可以使用 color.NRGBAModel 转换器(而不是 color.RGBAModel)。