65 lines
1.6 KiB
Go
65 lines
1.6 KiB
Go
package photoprism
|
|
|
|
import (
|
|
"fmt"
|
|
"image/color"
|
|
"math"
|
|
|
|
"github.com/lucasb-eyer/go-colorful"
|
|
|
|
"github.com/photoprism/photoprism/internal/thumb"
|
|
"github.com/photoprism/photoprism/pkg/colors"
|
|
"github.com/photoprism/photoprism/pkg/txt"
|
|
)
|
|
|
|
// Colors returns the ColorPerception of an image (only JPEG supported).
|
|
func (m *MediaFile) Colors(thumbPath string) (perception colors.ColorPerception, err error) {
|
|
if !m.IsJpeg() {
|
|
return perception, fmt.Errorf("%s is not a jpeg", txt.Quote(m.BaseName()))
|
|
}
|
|
|
|
img, err := m.Resample(thumbPath, thumb.Colors)
|
|
|
|
if err != nil {
|
|
log.Debugf("colors: %s in %s (resample)", err, txt.Quote(m.BaseName()))
|
|
return perception, err
|
|
}
|
|
|
|
bounds := img.Bounds()
|
|
width, height := bounds.Max.X, bounds.Max.Y
|
|
pixels := float64(width * height)
|
|
chromaSum := 0.0
|
|
|
|
colorCount := make(map[colors.Color]uint16)
|
|
var mainColorCount uint16
|
|
|
|
for y := 0; y < height; y++ {
|
|
for x := 0; x < width; x++ {
|
|
r, g, b, a := img.At(x, y).RGBA()
|
|
rgb, _ := colorful.MakeColor(color.RGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(a)})
|
|
i := colors.Colorful(rgb)
|
|
perception.Colors = append(perception.Colors, i)
|
|
|
|
if _, ok := colorCount[i]; ok == true {
|
|
colorCount[i] += colors.Weights[i]
|
|
} else {
|
|
colorCount[i] = colors.Weights[i]
|
|
}
|
|
|
|
if colorCount[i] > mainColorCount {
|
|
mainColorCount = colorCount[i]
|
|
perception.MainColor = i
|
|
}
|
|
|
|
_, c, l := rgb.Hcl()
|
|
|
|
chromaSum += c
|
|
|
|
perception.Luminance = append(perception.Luminance, colors.Luminance(math.Round(l*15)))
|
|
}
|
|
}
|
|
|
|
perception.Chroma = colors.Chroma(math.Round((chromaSum / pixels) * 100))
|
|
|
|
return perception, nil
|
|
}
|