2015-10-17 9 views
7

Potrzebuję uzyskać tablicę pikseli w postaci []byte, która zostanie przekazana do metody texImage2D z Contex z pakietu /mobile/gl.Uzyskaj tablicę pikselową z obrazu golang.Image

Potrzebuje tablicy pikseli, w której wartości rgba każdego piksela są dodawane w kolejności pikseli od lewej do prawej, od góry do dołu. Obecnie mam obraz załadowany z pliku.

a, err := asset.Open("key.jpeg") 
if err != nil { 
    log.Fatal(err) 
} 
defer a.Close() 

img, _, err := image.Decode(a) 
if err != nil { 
    log.Fatal(err) 
} 

szukam czegoś jak img.Pixels()

+1

To może być przydatna: https://godoc.org/golang.org/x/mobile/exp/gl/glutil#Image –

+0

[Image dokumentacja pakietu] (https://tip.golang.org/pkg/image/#Image) czyni to oczywistym. –

+0

@DaveC sugerujesz, że powinienem przejrzeć każdy piksel i użyć metody 'At', aby uzyskać kolor, i użyć metody' RGBA' koloru, by uzyskać wartości kolorów w kolorze rgba w formacie 32 uint32 i jakoś przekonwertować je na uint8? Przykro mi, ale nie jest to dla mnie oczywiste :(A nie wierzysz, że pomimo dokumentacji, to pytanie lepiej mieć odpowiedź na WR? Jeśli jest to "oczywiste", rozważ dodanie odpowiedzi. nie do mety upstream :) –

Odpowiedz

3

To, co skończyło się robi. Używam funkcji Draw image/draw innych pakietów, aby napełnić instancji image.RGBA

rect := img.Bounds() 
rgba := image.NewRGBA(rect) 
draw.Draw(rgba, rect, img, rect.Min, draw.Src) 

Teraz rgba.Pix zawiera tablicę chcę i może być stosowany w metodzie 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) 

Alternatywnie

Image przypadki zawiera At metody zwracającej Color. Dzięki temu można przechodzić przez każdy piksel i zbierać kolory. Ale konwersja zwróconych wartości rgba z Color może być skomplikowana. Cytowanie dokumentacja:

// 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. 
+0

Chciałbym sprawdzić, czy obraz jest już najpierw RGBA i po prostu użyć Pix bezpośrednio w tym przypadku. Używanie 'At' nie jest skomplikowane, jest to po prostu nieefektywne, dlatego mamy dostęp do Pix. – JimB

+1

W rzeczywistości użycie funkcji At nie jest takie trudne ... 'r, g, b, a: = image.At (x, y) .RGBA()' a następnie 'czerwony: = uint8 (r >> 8) 'itp. – Octopus

5

można po prostu użyć img.At(x, y).RGBA() aby uzyskać wartości RBGA dla piksela, po prostu trzeba je podzielić przez 257, aby uzyskać reprezentację 8 bitów. Zaleciłbym zbudowanie własnej dwuwymiarowej tablicy pikseli. Oto możliwe wdrożenie, modyfikować je w zależności od potrzeb:

package main 

import (
    "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 array 
func 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 Pixel 
func 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 example 
type Pixel struct { 
    R int 
    G int 
    B int 
    A int 
} 
+0

Dlaczego 257? Dlaczego nie 256? – Octopus

+1

Wartości są mnożone przez 101 w podstawie 16, co oznacza 257 w podstawie 10. Nie pamiętam, co jest specjalnego w liczbie lub dlaczego tak się dzieje, ale wynik powinien być liczbą całkowitą <256, w przeciwnym razie masz inna reprezentacja pikseli (zależy od typu img). – Kesarion

Powiązane problemy