Недялко обнови решението на 12.11.2013 14:51 (преди над 4 години)
+package main
+
+import "fmt"
+
+type Header struct {
+ Format string
+ LineWidth int
+}
+
+type Color struct {
+ Red, Green, Blue byte
+}
+
+func (c Color) String() string {
+ return fmt.Sprintf("Red: %d, Green: %d, Blue: %d", c.Red, c.Green, c.Blue)
+}
+
+type Pixel struct {
+ c Color
+}
+
+func (p Pixel) Color() Color {
+ return p.c
+}
+
+type Image struct {
+ Width, Height int
+ Data []Pixel
+}
+
+func (i Image) InspectPixel(col, row int) Pixel {
+ return i.Data[row*i.Width+col]
+}
+
+func MakePixel(format string, pixelData []byte) Pixel {
+ var red, green, blue byte
+ var alpha float32 = 255
+
+ // TODO: parse the format string only once and return a
+ // closure that makes custom pixels according to that header
+ for i := range format {
+ switch {
+ case format[i] == 'R':
+ red = pixelData[i]
+ case format[i] == 'G':
+ green = pixelData[i]
+ case format[i] == 'B':
+ blue = pixelData[i]
+ case format[i] == 'A':
+ alpha = float32(pixelData[i])
+ }
+ }
+
+ red = byte(float32(red) * alpha / 255)
+ green = byte(float32(green) * alpha / 255)
+ blue = byte(float32(blue) * alpha / 255)
+
+ return Pixel{Color{red, green, blue}}
+}
+
+func ParseImage(data []byte, header Header) Image {
+ dataLength := len(data)
+ pixelDataLength := len(header.Format)
+
+ pixelCount := dataLength / pixelDataLength
+ imageWidth := header.LineWidth
+ imageHeight := pixelCount / imageWidth
+
+ var img = new(Image)
+ img.Data = make([]Pixel, imageWidth*imageHeight)
+ img.Width = imageWidth
+ img.Height = imageHeight
+
+ for i := 0; i < pixelCount; i++ {
+ img.Data[i] = MakePixel(header.Format, data[i*pixelDataLength:(i+1)*pixelDataLength])
+ }
+
+ return *img
+}