Дойчин обнови решението на 05.11.2013 17:49 (преди над 4 години)
+package main
+
+import (
+ "fmt"
+ "math"
+)
+
+type Header struct {
+ Format string
+ LineWidth uint
+}
+
+type Pixel struct {
+ Red byte
+ Green byte
+ Blue byte
+ Alpha byte
+ normalized bool
+}
+
+// In case *someone* calls us with a wrong method name
+func (pixel *Pixel) Color() Pixel {
+ return pixel.Colour()
+}
+
+// quack quack!
+func (pixel *Pixel) Colour() Pixel {
+ return *pixel
+}
+
+func (pixel *Pixel) normalize() {
+ if pixel.normalized {
+ return
+ }
+
+ pixel.normalized = true
+
+ if pixel.Alpha == 0 || pixel.Alpha == 255 {
+ return
+ }
+
+ alpha := (float64)(pixel.Alpha) / 255.0
+
+ pixel.Red = alphaBlend(pixel.Red, alpha)
+ pixel.Green = alphaBlend(pixel.Green, alpha)
+ pixel.Blue = alphaBlend(pixel.Blue, alpha)
+
+}
+
+func (pixel Pixel) String() string {
+ return fmt.Sprintf("Red: %d, Green: %d, Blue: %d", pixel.Red, pixel.Green,
+ pixel.Blue)
+}
+
+type Image struct {
+ header Header
+ data []Pixel
+}
+
+func (img *Image) InspectPixel(x uint, y uint) Pixel {
+ index := y*img.header.LineWidth + x
+ return img.data[index]
+}
+
+func ParseImage(data []byte, header Header) *Image {
+ image := new(Image)
+ image.header = header
+
+ var pixel *Pixel
+ format_len := len(header.Format)
+
+ for index, colour_intensity := range data {
+
+ format_index := index % format_len
+ if format_index == 0 {
+ pixel = new(Pixel)
+ }
+
+ colour := header.Format[format_index]
+
+ switch (string)(colour) {
+ case "R":
+ pixel.Red = colour_intensity
+ case "G":
+ pixel.Green = colour_intensity
+ case "B":
+ pixel.Blue = colour_intensity
+ case "A":
+ pixel.Alpha = colour_intensity
+ }
+
+ if format_index == format_len-1 {
+ pixel.normalize()
+ image.data = append(image.data, *pixel)
+ }
+
+ }
+
+ return image
+}
+
+// Really? Go has no Round function of its own?
+func round(num float64) float64 {
+ floored := math.Floor(num)
+ diff := num - floored
+ if diff < 0.5 {
+ return floored
+ }
+ return math.Ceil(num)
+}
+
+func alphaBlend(colour byte, alpha float64) byte {
+ return (byte)(round(((float64)(colour) * alpha)))
+}