MTAutocolors/cmd/mtautocolors/images.go

88 lines
1.5 KiB
Go

// 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
}