去图像处理
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.RGBAModel
。 color.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
)。
我需要加载图像并搜索颜色并替换它们。例如,在图像上我需要搜索所有红色像素并将它们转换为紫色。
我正在执行以下操作(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.RGBAModel
。 color.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
)。