Мартин обнови решението на 08.11.2013 14:12 (преди над 4 години)
+package main
+
+import (
+ "fmt"
+ "strings"
+)
+
+type Header struct {
+ Format string
+ LineWidth uint
+}
+
+type Pixel struct {
+ Red, Green, Blue byte
+}
+
+func (p *Pixel) Color() Pixel {
+ return *p
+}
+
+type Image struct {
+ pixels [][]Pixel
+}
+
+func InArray(needle string, haystack []string) bool {
+ for _, value := range haystack {
+ if value == needle {
+ return true
+ }
+ }
+ return false
+}
+
+func (i *Image) InspectPixel(x uint, y uint) Pixel {
+ return i.pixels[x][y]
+}
+
+func ParseImage(data []byte, header Header) *Image {
+ allowedFormats := []string{"RGB", "RGBA", "BGRA"}
+
+ if !InArray(header.Format, allowedFormats) {
+ panic("Unknown format: " + header.Format)
+ }
+ if (len(data) % (int(header.LineWidth) * len(header.Format))) != 0 {
+ panic("Invalid Line Width")
+ }
+
+ step := len(header.Format)
+ order := strings.Split(header.Format, "")
+ columns := int(header.LineWidth)
+ rows := len(data) / (step * int(header.LineWidth))
+ pixels := make([][]Pixel, columns)
+
+ for i := 0; i < len(pixels); i++ {
+ pixels[i] = make([]Pixel, rows)
+ for j := 0; j < len(pixels[i]); j++ {
+ pixels[i][j] = Pixel{}
+ orderStep := 0
+ for _, value := range order {
+ curByte := data[(i*rows+j)*step+orderStep]
+ switch value {
+ case "R":
+ pixels[i][j].Red = curByte
+ case "G":
+ pixels[i][j].Green = curByte
+ case "B":
+ pixels[i][j].Blue = curByte
+ case "A":
+ pixels[i][j].Red =
+ byte((int(pixels[i][j].Red) * int(curByte)) / 255)
+ pixels[i][j].Green =
+ byte((int(pixels[i][j].Green) * int(curByte)) / 255)
+ pixels[i][j].Blue =
+ byte((int(pixels[i][j].Blue) * int(curByte)) / 255)
+ }
+ orderStep++
+ }
+ }
+ }
+ return &Image{pixels}
+}
+
+func main() {
+ data := []byte{
+ 0, 12, 244, 128, 14, 26, 52, 127, 31, 33, 41, 255, 36, 133, 241, 255,
+ }
+ header := Header{"RGBA", 4}
+ pixel := ParseImage(data, header).InspectPixel(3, 0)
+ fmt.Println(pixel.Color())
+}