我是Go的新手,并试图提高我的技能。目前我正在使用图像,我需要将图像的所有像素都设置为红色值。我知道我可以使用下面的代码实现这一点,但对我来说似乎很慢(~485毫秒),
pixList := make([]uint8, width*height)
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
r, _, _, _ := img.At(x, y).RGBA()
var rNew uint8 = uint8(float32(r)*(255.0/65535.0))
pixList[(x*height)+y] = rNew
}
}
有没有更快的方法呢?任何内置函数一次性获取所有像素值?
编辑:我现在正在使用Pix获取所有像素数据,但我的Pix列表仍未提供我正在寻找的内容。
新代码:
pixList := img.(*image.Paletted).Pix
newPixList := make([]uint8, width*height)
fmt.Println(len(pixList))//gives width*height, shouldn't it be width*height*4?
for index := 0; index < width*height; index++ {
newPixList[index] = pixList[index*4]//this part gives index out of range error, because the pixList is length of width*height, i dunno why
}
我认为这不是我的形象,因为它是一个rgba图像,也许转换可以工作。有什么想法吗?
感谢。
答案 0 :(得分:1)
您无法使此模式具有高性能,因为这需要为每个像素调用接口方法。要快速访问图像数据,您可以直接访问图像数据。以image.RGBA
类型为例:
type RGBA struct {
// Pix holds the image's pixels, in R, G, B, A order. The pixel at
// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
Pix []uint8
// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
Stride int
// Rect is the image's bounds.
Rect Rectangle
}
每种图像类型的文档都包括数据布局和索引公式。对于此类型,您可以使用以下内容从Pix
切片中提取所有红色像素:
w, h := img.Rect.Dx(), img.Rect.Dy()
pixList := make([]uint8, w*h)
for i := 0; i < w*h; i++ {
pixList[i] = img.Pix[i*4]
}
如果需要转换其他图像类型,可以使用现有方法进行颜色转换,但首先断言正确的图像类型并使用本机*At
方法来避免接口调用。从YCbCr图像中提取近似红色值:
w, h := img.Rect.Dx(), img.Rect.Dy()
pixList := make([]uint8, w*h)
for x := 0; x < w; x++ {
for y := 0; y < h; y++ {
r, _, _, _ := img.YCbCrAt(x, y).RGBA()
pixList[(x*h)+y] = uint8(r >> 8)
}
}
return pixList
类似于上面的YCbCr图像没有&#34;红色&#34;像素(需要为每个单独的像素计算值),调色板图像没有像素的单独RGBA值,需要在图像的调色板中查找。您可以更进一步,并预先确定调色板颜色的颜色模型,以删除Color.RGBA()
接口调用,以加快速度,更加如此:
palette := make([]*color.RGBA, len(img.Palette))
for i, c := range img.Palette {
palette[i] = c.(*color.RGBA)
}
pixList := make([]uint8, len(img.Pix))
for i, p := range img.Pix {
pixList[i] = palette[p].R
}