From 3cf0e9f8575c9ce8581f7f981d054744c8033b1a Mon Sep 17 00:00:00 2001 From: velvettear Date: Tue, 21 Nov 2023 16:48:32 +0100 Subject: [PATCH] added parameters to configure the color palette --- .vscode/launch.json | 8 ++++++-- README.md | 27 +++++++++++++++++++-------- internal/config/config.go | 29 +++++++++++++++++++++-------- internal/slideshow/palette.go | 14 ++++++++------ internal/slideshow/slideshow.go | 4 ++-- slideshow.service | 2 ++ 6 files changed, 58 insertions(+), 26 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 549a66e..01b3f23 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,9 @@ "SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_RESOLUTION": "600x1024", "SLIDESHOW_LOGLEVEL": "debug", - "SLIDESHOW_PALETTE": "/tmp/slideshow.palette" + "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette", + "SLIDESHOW_PALETTE_ALGORITHM": "wsm", + "SLIDESHOW_PALETTE_COLORS": "32" }, "console": "integratedTerminal" }, @@ -26,7 +28,9 @@ "SLIDESHOW_INTERVAL": "10", "SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_LOGLEVEL": "debug", - "SLIDESHOW_PALETTE": "/tmp/slideshow.palette" + "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette", + "SLIDESHOW_PALETTE_ALGORITHM": "wsm", + "SLIDESHOW_PALETTE_COLORS": "16" }, "console": "integratedTerminal" } diff --git a/README.md b/README.md index f640861..46d5637 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,15 @@ a simple cli application to start a background image slideshow using 'feh'. configuration is entirely done via environment variables. -| variable | default | description | -| -------------------- | ----------------- | -----------------------------------------------------------| -| SLIDESHOW_INTERVAL | 60 | the interval of the slideshow in seconds | -| SLIDESHOW_DIRECTORY | "$HOME" | path to a directory containing images | -| 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_LOGLEVEL | "info" | the log level | +| variable | default | description | +| --------------------------- | ----------------- | -----------------------------------------------------------| +| SLIDESHOW_INTERVAL | 60 | the interval of the slideshow in seconds | +| SLIDESHOW_DIRECTORY | "$HOME" | path to a directory containing images | +| 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_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:** if no resolution is set the images will be displayed as they are (without any scaling). @@ -28,4 +30,13 @@ if no resolution is set the images will be displayed as they are (without any sc - `info` - `warning` - `error` -- `fatal` \ No newline at end of file +- `fatal` + +## color palette + +**available algorithms:** + +- `wsm` +- `wu` + +for more information regarding the color palette see [color-thief](https://github.com/kennykarnama/color-thief). diff --git a/internal/config/config.go b/internal/config/config.go index 49a6143..2c85589 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,16 +12,18 @@ import ( var Interval time.Duration var Directory string var Resolution string -var Palette string +var PaletteFile string +var PaletteAlgorithm int +var PaletteColors int // initialize the config func Initialize() { loggo.SetLogLevelByName(os.Getenv("SLIDESHOW_LOGLEVEL")) - tmp, _ := strconv.Atoi(os.Getenv("SLIDESHOW_INTERVAL")) - if tmp <= 0 { - tmp = 60 + tmpInt, _ := strconv.Atoi(os.Getenv("SLIDESHOW_INTERVAL")) + if tmpInt <= 0 { + tmpInt = 60 } - Interval = time.Duration(tmp) * time.Second + Interval = time.Duration(tmpInt) * time.Second Directory = os.Getenv("SLIDESHOW_DIRECTORY") if len(Directory) == 0 { tmp, error := os.UserHomeDir() @@ -52,7 +54,18 @@ func Initialize() { 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 @@ -60,7 +73,7 @@ func IsResolutionSet() bool { return len(Resolution) > 0 } -// check if a socket has been set +// check if a color palette should be generated func IsPaletteSet() bool { - return len(Palette) > 0 + return len(PaletteFile) > 0 } diff --git a/internal/slideshow/palette.go b/internal/slideshow/palette.go index bc12de7..5f16e1e 100644 --- a/internal/slideshow/palette.go +++ b/internal/slideshow/palette.go @@ -32,27 +32,28 @@ func exportPalette(colors []color.Color) { tmp = "SLIDESHOW_COLOR" + tmp palette += tmp + "=\"" + rgbToHex(color) + "\"" } - error := os.WriteFile(config.Palette, []byte(palette), 0775) + error := os.WriteFile(config.PaletteFile, []byte(palette), 0775) if error != nil { loggo.ErrorTimed("encountered an error exporting a color palette", timestamp, error.Error()) } 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 -func getColorPaletteRaw(data []byte, amount int) ([]color.Color, error) { +func getColorPaletteRaw(data []byte) ([]color.Color, error) { var colors []color.Color if !config.IsPaletteSet() { return colors, nil } timestamp := time.Now().UnixMilli() + amount := config.PaletteColors img, _, error := image.Decode(bytes.NewReader(data)) if error != nil { loggo.ErrorTimed("encountered an error decoding the provided raw image bytes to an image", timestamp, error.Error()) return colors, error } - colors, error = color_thief.GetPalette(img, amount, 0) + colors, error = color_thief.GetPalette(img, amount, config.PaletteAlgorithm) if error != nil { loggo.ErrorTimed("encountered an error generating the color palette from raw image bytes", timestamp, "colors: "+strconv.Itoa(amount)) } else { @@ -62,13 +63,14 @@ func getColorPaletteRaw(data []byte, amount int) ([]color.Color, error) { } // 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 if !config.IsPaletteSet() { return colors, nil } 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 { loggo.ErrorTimed("encountered an error generating the color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount)) } else { diff --git a/internal/slideshow/slideshow.go b/internal/slideshow/slideshow.go index ddf0d15..971ce9a 100644 --- a/internal/slideshow/slideshow.go +++ b/internal/slideshow/slideshow.go @@ -42,9 +42,9 @@ func Start() { } data = tmp scaleTime = time.Since(scaleTimestamp) - palette, _ = getColorPaletteRaw(data, 16) + palette, _ = getColorPaletteRaw(data) } else { - palette, _ = getColorPalette(image, 16) + palette, _ = getColorPalette(image) } if sleepTime > 0 { loggo.Debug("sleeping for " + strconv.FormatInt(sleepTime.Milliseconds(), 10) + "ms") diff --git a/slideshow.service b/slideshow.service index 8ce6196..7eb9d6d 100644 --- a/slideshow.service +++ b/slideshow.service @@ -10,6 +10,8 @@ Environment="SLIDESHOW_DIRECTORY=$HOME" Environment="SLIDESHOW_RESOLUTION=1920x1080" Environment="SLIDESHOW_LOGLEVEL=info" Environment="SLIDESHOW_PALETTE=/tmp/.slideshow.palette" +Environment="SLIDESHOW_PALETTE_ALGORITHM=wsm" +Environment="SLIDESHOW_PALETTE_COLORS=16" ExecStart=/opt/slideshow/slideshow [Install]