获取所有像素值(rgba)

时间:2016-06-05 15:06:39

标签: image go

我是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图像,也许转换可以工作。有什么想法吗?

感谢。

1 个答案:

答案 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
}