-
蝴蝶刀刀
您可以简单地使用img.At(x, y).RGBA()获取像素的 RBGA 值,只需将它们除以 257 即可获得 8 位表示。我建议构建您自己的二维像素阵列。这是一个可能的实现,根据需要修改它:package mainimport ( "fmt" "image" "image/png" "os" "io" "net/http")func main() { // You can register another format here image.RegisterFormat("png", "png", png.Decode, png.DecodeConfig) file, err := os.Open("./image.png") if err != nil { fmt.Println("Error: File could not be opened") os.Exit(1) } defer file.Close() pixels, err := getPixels(file) if err != nil { fmt.Println("Error: Image could not be decoded") os.Exit(1) } fmt.Println(pixels)}// Get the bi-dimensional pixel arrayfunc getPixels(file io.Reader) ([][]Pixel, error) { img, _, err := image.Decode(file) if err != nil { return nil, err } bounds := img.Bounds() width, height := bounds.Max.X, bounds.Max.Y var pixels [][]Pixel for y := 0; y < height; y++ { var row []Pixel for x := 0; x < width; x++ { row = append(row, rgbaToPixel(img.At(x, y).RGBA())) } pixels = append(pixels, row) } return pixels, nil}// img.At(x, y).RGBA() returns four uint32 values; we want a Pixelfunc rgbaToPixel(r uint32, g uint32, b uint32, a uint32) Pixel { return Pixel{int(r / 257), int(g / 257), int(b / 257), int(a / 257)}}// Pixel struct exampletype Pixel struct { R int G int B int A int}
-
慕斯王
这就是我最终要做的。我正在使用image/draw包的 Draw 函数来重新填充image.RGBA实例rect := img.Bounds()rgba := image.NewRGBA(rect)draw.Draw(rgba, rect, img, rect.Min, draw.Src)现在rgba.Pix包含我想要的数组并且可以在TexImage2D方法中使用。glctx.TexImage2D(gl.TEXTURE_2D, 0, rect.Max.X-rect.Min.X, rect.Max.Y-rect.Min.Y, gl.RGBA, gl.UNSIGNED_BYTE, rgba.Pix)交替Image实例包含一个At返回Color的方法。因此可以遍历每个像素并收集颜色。但是从 转换返回的 rgba 值Color可能很复杂。引用文档: // 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.
-
郎朗坤
在我的测试中,Pixmethod 显示比快 4 倍At,但仍然需要太长时间......这是我的测试脚本,不确定height/width顺序,但这对我有用:// test_image_time.gopackage mainimport ( "os" "fmt" "image" _ "image/jpeg" "golang.org/x/image/draw" "time")func main() { img_path:= "/path/to/image/.jpg" aa := time.Now() reader, _ := os.Open(img_path) m, _, _ := image.Decode(reader) bounds := m.Bounds() fmt.Println("Bounds: ", bounds.Min.Y, bounds.Max.Y, bounds.Min.X, bounds.Max.X) bb := time.Now() fmt.Println("Read file time: ", float64(bb.Nanosecond() - aa.Nanosecond()) / 1e9) aa = time.Now() _ = image_2_array_at(m) bb = time.Now() fmt.Println("At Time: ", float64(bb.Nanosecond() - aa.Nanosecond()) / 1e9) aa = time.Now() _ = image_2_array_pix(m) bb = time.Now() fmt.Println("Pix Time: ", float64(bb.Nanosecond() - aa.Nanosecond()) / 1e9)}func image_2_array_at(src image.Image) [][][3]float32 { bounds := src.Bounds() width, height := bounds.Max.X, bounds.Max.Y iaa := make([][][3]float32, height) for y := 0; y < height; y++ { row := make([][3]float32, width) for x := 0; x < width; x++ { r, g, b, _ := src.At(x, y).RGBA() // A color's RGBA method returns values in the range [0, 65535]. // Shifting by 8 reduces this to the range [0, 255]. row[x] = [3]float32{float32(r>>8), float32(g>>8), float32(b>>8)} } iaa[y] = row } return iaa}func image_2_array_pix(src image.Image) [][][3]float32 { bounds := src.Bounds() width, height := bounds.Max.X, bounds.Max.Y iaa := make([][][3]float32, height) src_rgba := image.NewRGBA(src.Bounds()) draw.Copy(src_rgba, image.Point{}, src, src.Bounds(), draw.Src, nil) for y := 0; y < height; y++ { row := make([][3]float32, width) for x := 0; x < width; x++ { idx_s := (y * width + x) * 4 pix := src_rgba.Pix[idx_s : idx_s + 4] row[x] = [3]float32{float32(pix[0]), float32(pix[1]), float32(pix[2])} } iaa[y] = row } return iaa}跑$ go run test_image_time.goBounds: 0 976 0 1920Read file time: 0.025212067At Time: 0.069091218Pix Time: 0.0165787