added parameters to configure the color palette

This commit is contained in:
Daniel Sommer 2023-11-21 16:48:32 +01:00
parent 2b26dd2ee0
commit 3cf0e9f857
6 changed files with 58 additions and 26 deletions

8
.vscode/launch.json vendored
View file

@ -12,7 +12,9 @@
"SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_DIRECTORY": "/home/velvettear/images",
"SLIDESHOW_RESOLUTION": "600x1024", "SLIDESHOW_RESOLUTION": "600x1024",
"SLIDESHOW_LOGLEVEL": "debug", "SLIDESHOW_LOGLEVEL": "debug",
"SLIDESHOW_PALETTE": "/tmp/slideshow.palette" "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette",
"SLIDESHOW_PALETTE_ALGORITHM": "wsm",
"SLIDESHOW_PALETTE_COLORS": "32"
}, },
"console": "integratedTerminal" "console": "integratedTerminal"
}, },
@ -26,7 +28,9 @@
"SLIDESHOW_INTERVAL": "10", "SLIDESHOW_INTERVAL": "10",
"SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_DIRECTORY": "/home/velvettear/images",
"SLIDESHOW_LOGLEVEL": "debug", "SLIDESHOW_LOGLEVEL": "debug",
"SLIDESHOW_PALETTE": "/tmp/slideshow.palette" "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette",
"SLIDESHOW_PALETTE_ALGORITHM": "wsm",
"SLIDESHOW_PALETTE_COLORS": "16"
}, },
"console": "integratedTerminal" "console": "integratedTerminal"
} }

View file

@ -11,13 +11,15 @@ a simple cli application to start a background image slideshow using 'feh'.
configuration is entirely done via environment variables. configuration is entirely done via environment variables.
| variable | default | description | | variable | default | description |
| -------------------- | ----------------- | -----------------------------------------------------------| | --------------------------- | ----------------- | -----------------------------------------------------------|
| SLIDESHOW_INTERVAL | 60 | the interval of the slideshow in seconds | | SLIDESHOW_INTERVAL | 60 | the interval of the slideshow in seconds |
| SLIDESHOW_DIRECTORY | "$HOME" | path to a directory containing images | | SLIDESHOW_DIRECTORY | "$HOME" | path to a directory containing images |
| SLIDESHOW_RESOLUTION | | the resolution to which images are scaled (i.e. 1920x1080) | | SLIDESHOW_RESOLUTION | | the resolution to which images are scaled (i.e. 1920x1080) |
| SLIDESHOW_PALETTE | | path to a file where the color palette will be stored | | SLIDESHOW_PALETTE | | path to a file where the color palette will be stored |
| SLIDESHOW_LOGLEVEL | "info" | the log level | | SLIDESHOW_PALETTE_ALGORITHM | "wsm" | the algorithm used to generate the color palette |
| SLIDESHOW_PALETTE_COLORS | 16 | the amount of colors generated |
| SLIDESHOW_LOGLEVEL | "info" | the log level |
**note:** **note:**
if no resolution is set the images will be displayed as they are (without any scaling). if no resolution is set the images will be displayed as they are (without any scaling).
@ -29,3 +31,12 @@ if no resolution is set the images will be displayed as they are (without any sc
- `warning` - `warning`
- `error` - `error`
- `fatal` - `fatal`
## color palette
**available algorithms:**
- `wsm`
- `wu`
for more information regarding the color palette see [color-thief](https://github.com/kennykarnama/color-thief).

View file

@ -12,16 +12,18 @@ import (
var Interval time.Duration var Interval time.Duration
var Directory string var Directory string
var Resolution string var Resolution string
var Palette string var PaletteFile string
var PaletteAlgorithm int
var PaletteColors int
// initialize the config // initialize the config
func Initialize() { func Initialize() {
loggo.SetLogLevelByName(os.Getenv("SLIDESHOW_LOGLEVEL")) loggo.SetLogLevelByName(os.Getenv("SLIDESHOW_LOGLEVEL"))
tmp, _ := strconv.Atoi(os.Getenv("SLIDESHOW_INTERVAL")) tmpInt, _ := strconv.Atoi(os.Getenv("SLIDESHOW_INTERVAL"))
if tmp <= 0 { if tmpInt <= 0 {
tmp = 60 tmpInt = 60
} }
Interval = time.Duration(tmp) * time.Second Interval = time.Duration(tmpInt) * time.Second
Directory = os.Getenv("SLIDESHOW_DIRECTORY") Directory = os.Getenv("SLIDESHOW_DIRECTORY")
if len(Directory) == 0 { if len(Directory) == 0 {
tmp, error := os.UserHomeDir() tmp, error := os.UserHomeDir()
@ -52,7 +54,18 @@ func Initialize() {
loggo.Fatal("encountered an error parsing the configured height '" + height + "'") loggo.Fatal("encountered an error parsing the configured height '" + height + "'")
} }
} }
Palette = os.Getenv("SLIDESHOW_PALETTE") PaletteFile = os.Getenv("SLIDESHOW_PALETTE")
tmpString := os.Getenv("SLIDESHOW_PALETTE_ALGORITHM")
if strings.ToLower(tmpString) == "wu" {
PaletteAlgorithm = 0
} else {
PaletteAlgorithm = 1
}
tmpInt, _ = strconv.Atoi(os.Getenv("SLIDESHOW_PALETTE_COLORS"))
if tmpInt <= 0 {
tmpInt = 16
}
PaletteColors = tmpInt
} }
// check if a resolution has been specified // check if a resolution has been specified
@ -60,7 +73,7 @@ func IsResolutionSet() bool {
return len(Resolution) > 0 return len(Resolution) > 0
} }
// check if a socket has been set // check if a color palette should be generated
func IsPaletteSet() bool { func IsPaletteSet() bool {
return len(Palette) > 0 return len(PaletteFile) > 0
} }

View file

@ -32,27 +32,28 @@ func exportPalette(colors []color.Color) {
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.PaletteFile, []byte(palette), 0775)
if error != nil { if error != nil {
loggo.ErrorTimed("encountered an error exporting a color palette", timestamp, error.Error()) loggo.ErrorTimed("encountered an error exporting a color palette", timestamp, error.Error())
} else { } else {
loggo.DebugTimed("exported color palette to filesystem", timestamp, "path: "+config.Palette) loggo.DebugTimed("exported color palette to filesystem", timestamp, "path: "+config.PaletteFile)
} }
} }
// extract the given amount of dominant colors of raw image bytes // extract the given amount of dominant colors of raw image bytes
func getColorPaletteRaw(data []byte, amount int) ([]color.Color, error) { func getColorPaletteRaw(data []byte) ([]color.Color, error) {
var colors []color.Color var colors []color.Color
if !config.IsPaletteSet() { if !config.IsPaletteSet() {
return colors, nil return colors, nil
} }
timestamp := time.Now().UnixMilli() timestamp := time.Now().UnixMilli()
amount := config.PaletteColors
img, _, error := image.Decode(bytes.NewReader(data)) img, _, error := image.Decode(bytes.NewReader(data))
if error != nil { if error != nil {
loggo.ErrorTimed("encountered an error decoding the provided raw image bytes to an image", timestamp, error.Error()) loggo.ErrorTimed("encountered an error decoding the provided raw image bytes to an image", timestamp, error.Error())
return colors, error return colors, error
} }
colors, error = color_thief.GetPalette(img, amount, 0) colors, error = color_thief.GetPalette(img, amount, config.PaletteAlgorithm)
if error != nil { if error != nil {
loggo.ErrorTimed("encountered an error generating the color palette from raw image bytes", timestamp, "colors: "+strconv.Itoa(amount)) loggo.ErrorTimed("encountered an error generating the color palette from raw image bytes", timestamp, "colors: "+strconv.Itoa(amount))
} else { } else {
@ -62,13 +63,14 @@ func getColorPaletteRaw(data []byte, amount int) ([]color.Color, error) {
} }
// extract the given amount of dominant colors of 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) ([]color.Color, error) {
var colors []color.Color var colors []color.Color
if !config.IsPaletteSet() { if !config.IsPaletteSet() {
return colors, nil return colors, nil
} }
timestamp := time.Now().UnixMilli() timestamp := time.Now().UnixMilli()
colors, error := color_thief.GetPaletteFromFile(image, amount, 0) amount := config.PaletteColors
colors, error := color_thief.GetPaletteFromFile(image, amount, config.PaletteAlgorithm)
if error != nil { if error != nil {
loggo.ErrorTimed("encountered an error generating the color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount)) loggo.ErrorTimed("encountered an error generating the color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount))
} else { } else {

View file

@ -42,9 +42,9 @@ func Start() {
} }
data = tmp data = tmp
scaleTime = time.Since(scaleTimestamp) scaleTime = time.Since(scaleTimestamp)
palette, _ = getColorPaletteRaw(data, 16) palette, _ = getColorPaletteRaw(data)
} else { } else {
palette, _ = getColorPalette(image, 16) palette, _ = getColorPalette(image)
} }
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")

View file

@ -10,6 +10,8 @@ Environment="SLIDESHOW_DIRECTORY=$HOME"
Environment="SLIDESHOW_RESOLUTION=1920x1080" Environment="SLIDESHOW_RESOLUTION=1920x1080"
Environment="SLIDESHOW_LOGLEVEL=info" Environment="SLIDESHOW_LOGLEVEL=info"
Environment="SLIDESHOW_PALETTE=/tmp/.slideshow.palette" Environment="SLIDESHOW_PALETTE=/tmp/.slideshow.palette"
Environment="SLIDESHOW_PALETTE_ALGORITHM=wsm"
Environment="SLIDESHOW_PALETTE_COLORS=16"
ExecStart=/opt/slideshow/slideshow ExecStart=/opt/slideshow/slideshow
[Install] [Install]