Go图像处理

5

我需要加载一张图片并搜索其中的颜色,并将它们替换成其他颜色。例如,在一张图片上,我需要搜索所有红色像素并将它们转换成紫色。

我正在进行以下操作(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()似乎无法返回正确的R、G、B、A代码?例如,我得到的数字超过了255。

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

1个回答

10

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.
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(),它返回类型为image.RGBA的图像,因此Image.At()方法返回的颜色将是动态类型color.RGBA,所以您可以简单地使用类型断言

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()将返回一个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)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接