// Copyright 2015 by Sascha L. Teichmann // Use of this source code is governed by the MIT license // that can be found in the LICENSE file. package main import ( "bufio" "fmt" "image" "image/color" "image/draw" "os" _ "image/jpeg" _ "image/png" ) func loadRGBA(filename string) (*image.RGBA, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() var img image.Image if img, _, err = image.Decode(bufio.NewReader(file)); err != nil { return nil, fmt.Errorf("Decoding '%s' failed: %s", filename, err) } if rgba, ok := img.(*image.RGBA); ok { return rgba, nil } bounds := img.Bounds() rgba := image.NewRGBA(bounds) draw.Draw(rgba, bounds, img, image.ZP, draw.Src) return rgba, nil } func averageColor(filename string) (color.Color, error) { img, err := loadRGBA(filename) if err != nil { return nil, err } bounds := img.Bounds() if bounds.Empty() { return color.Black, nil } y := img.PixOffset(bounds.Min.X, bounds.Min.Y) yEnd := img.PixOffset(bounds.Min.X, bounds.Max.Y) w := bounds.Dx() * 4 pix := img.Pix var r, g, b, a uint64 for ; y < yEnd; y += img.Stride { for pos, end := y, y+w; pos < end; pos += 4 { pa := uint64(pix[pos+3]) r += pa * uint64(pix[pos]) g += pa * uint64(pix[pos+1]) b += pa * uint64(pix[pos+2]) a += pa } } r /= 255 g /= 255 b /= 255 if s := a / 255; s > 0 { r /= s g /= s b /= s } col := color.RGBA{ R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(a / uint64(bounds.Dx()*bounds.Dy()))} return &col, nil }