optimized color palette generation

This commit is contained in:
Daniel Sommer 2023-11-21 14:38:41 +01:00
parent d550414b7c
commit f8a12261ea
3 changed files with 51 additions and 24 deletions

16
.vscode/launch.json vendored
View file

@ -2,7 +2,7 @@
"version": "0.0.1", "version": "0.0.1",
"configurations": [ "configurations": [
{ {
"name": "slideshow", "name": "slideshow-scaled",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "auto", "mode": "auto",
@ -15,6 +15,20 @@
"SLIDESHOW_PALETTE": "/tmp/slideshow.palette" "SLIDESHOW_PALETTE": "/tmp/slideshow.palette"
}, },
"console": "integratedTerminal" "console": "integratedTerminal"
},
{
"name": "slideshow-unscaled",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env":{
"SLIDESHOW_INTERVAL": "10",
"SLIDESHOW_DIRECTORY": "/home/velvettear/images",
"SLIDESHOW_LOGLEVEL": "debug",
"SLIDESHOW_PALETTE": "/tmp/slideshow.palette"
},
"console": "integratedTerminal"
} }
] ]
} }

View file

@ -1,7 +1,9 @@
package slideshow package slideshow
import ( import (
"bytes"
"fmt" "fmt"
"image"
"image/color" "image/color"
"os" "os"
"strconv" "strconv"
@ -13,16 +15,11 @@ import (
) )
// write the base16 color palette to a file // write the base16 color palette to a file
func exportPalette(image string) { func exportPalette(colors []color.Color) {
if !config.IsPaletteSet() { if len(colors) == 0 || !config.IsPaletteSet() {
return return
} }
var palette string var palette string
colors, error := getColorPalette(image, 16)
if error != nil {
loggo.Error("encountered an error getting the color palette for image", "image: "+image, error.Error())
return
}
for index, color := range colors { for index, color := range colors {
if index > 0 { if index > 0 {
palette += "\n" palette += "\n"
@ -34,33 +31,44 @@ func exportPalette(image string) {
tmp = "SLIDESHOW_COLOR" + tmp tmp = "SLIDESHOW_COLOR" + tmp
palette += tmp + "=\"" + rgbToHex(color) + "\"" palette += tmp + "=\"" + rgbToHex(color) + "\""
} }
error = os.WriteFile(config.Palette, []byte(palette), 0775) error := os.WriteFile(config.Palette, []byte(palette), 0775)
if error != nil { if error != nil {
loggo.Error("encountered an error exporting the color palette for image", "image: "+image, error.Error()) loggo.Error("encountered an error exporting a color palette", error.Error())
} }
} }
// get the base16 color palette from an image // extract the given amount of dominant colors of raw image bytes
func GetBase16Colors(image string) (string, error) { func getColorPaletteRaw(data []byte, amount int) ([]color.Color, error) {
var base16 string var colors []color.Color
colors, error := getColorPalette(image, 16) if !config.IsPaletteSet() {
return colors, nil
}
timestamp := time.Now().UnixMilli()
img, _, error := image.Decode(bytes.NewReader(data))
if error != nil { if error != nil {
return base16, error loggo.ErrorTimed("encountered an error decoding the provided raw image bytes to an image", timestamp, error.Error())
return colors, error
} }
for index, color := range colors { colors, error = color_thief.GetPalette(img, amount, 0)
if index > 0 { if error != nil {
base16 += "\n" loggo.ErrorTimed("encountered an error generating the color palette from raw image bytes", timestamp, "colors: "+strconv.Itoa(amount))
} else {
loggo.DebugTimed("generated color palette from raw image bytes", timestamp, "colors: "+strconv.Itoa(amount))
} }
base16 += rgbToHex(color) return colors, error
}
return base16, nil
} }
// extract the given amount of dominant colors an image // extract the given amount of dominant colors of an image
func getColorPalette(image string, amount int) ([]color.Color, error) { func getColorPalette(image string, amount int) ([]color.Color, error) {
var colors []color.Color
if !config.IsPaletteSet() {
return colors, nil
}
timestamp := time.Now().UnixMilli() timestamp := time.Now().UnixMilli()
colors, error := color_thief.GetPaletteFromFile(image, amount, 0) colors, error := color_thief.GetPaletteFromFile(image, amount, 0)
if error == nil { if error != nil {
loggo.ErrorTimed("encountered an error generating the color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount))
} else {
loggo.DebugTimed("generated color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount)) loggo.DebugTimed("generated color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount))
} }
return colors, error return colors, error

View file

@ -2,6 +2,7 @@ package slideshow
import ( import (
"errors" "errors"
"image/color"
"io" "io"
"os/exec" "os/exec"
"strconv" "strconv"
@ -24,6 +25,7 @@ func Start() {
scaleImages := config.IsResolutionSet() scaleImages := config.IsResolutionSet()
for { for {
var image string var image string
var palette []color.Color
var data []byte var data []byte
for { for {
image = watcher.GetRandomImage() image = watcher.GetRandomImage()
@ -40,12 +42,15 @@ func Start() {
} }
data = tmp data = tmp
scaleTime = time.Since(scaleTimestamp) scaleTime = time.Since(scaleTimestamp)
palette, _ = getColorPaletteRaw(data, 16)
} else {
palette, _ = getColorPalette(image, 16)
} }
if sleepTime > 0 { if sleepTime > 0 {
loggo.Debug("sleeping for " + strconv.FormatInt(sleepTime.Milliseconds(), 10) + "ms") loggo.Debug("sleeping for " + strconv.FormatInt(sleepTime.Milliseconds(), 10) + "ms")
time.Sleep(sleepTime) time.Sleep(sleepTime)
} }
go exportPalette(image) go exportPalette(palette)
if scaleImages { if scaleImages {
error := setBackgroundPiped(data) error := setBackgroundPiped(data)
if error != nil { if error != nil {