diff --git a/.vscode/launch.json b/.vscode/launch.json index da4c53c..881313e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,8 @@ "SLIDESHOW_INTERVAL": "10", "SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_RESOLUTION": "600x1024", - "SLIDESHOW_LOGLEVEL": "debug" + "SLIDESHOW_LOGLEVEL": "debug", + "SLIDESHOW_PALETTE": "/tmp/slideshow.palette" }, "console": "integratedTerminal" } diff --git a/README.md b/README.md index 29e7064..f640861 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ configuration is entirely done via environment variables. | 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 | **note:** diff --git a/internal/config/config.go b/internal/config/config.go index 42c0b4c..49a6143 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,6 +12,7 @@ import ( var Interval time.Duration var Directory string var Resolution string +var Palette string // initialize the config func Initialize() { @@ -50,11 +51,16 @@ func Initialize() { if error != nil { loggo.Fatal("encountered an error parsing the configured height '" + height + "'") } - return } + Palette = os.Getenv("SLIDESHOW_PALETTE") } // check if a resolution has been specified func IsResolutionSet() bool { return len(Resolution) > 0 } + +// check if a socket has been set +func IsPaletteSet() bool { + return len(Palette) > 0 +} diff --git a/internal/slideshow/palette.go b/internal/slideshow/palette.go index ef0fef6..d2ee1cc 100644 --- a/internal/slideshow/palette.go +++ b/internal/slideshow/palette.go @@ -3,18 +3,61 @@ package slideshow import ( "fmt" "image/color" + "os" + "strconv" "time" "git.velvettear.de/velvettear/loggo" + "git.velvettear.de/velvettear/slideshow/internal/config" color_thief "github.com/kennykarnama/color-thief" ) -// extract the color palette from an image -func GetPalette(image string) ([]color.Color, error) { +// write the base16 color palette to a file +func exportPalette() error { + if !config.IsPaletteSet() { + return nil + } + var palette string + colors, error := getColorPalette(image, 16) + if error != nil { + return error + } + for index, color := range colors { + if index > 0 { + palette += "\n" + } + tmp := strconv.Itoa(index) + if len(tmp) < 2 { + tmp = "0" + tmp + } + tmp = "SLIDESHOW_COLOR" + tmp + palette += tmp + "=\"" + rgbToHex(color) + "\"" + } + return os.WriteFile(config.Palette, []byte(palette), 0775) +} + +// get the base16 color palette from an image +func GetBase16Colors(image string) (string, error) { + var base16 string + colors, error := getColorPalette(image, 16) + if error != nil { + return base16, error + } + for index, color := range colors { + if index > 0 { + base16 += "\n" + } + base16 += rgbToHex(color) + } + return base16, nil +} + +// extract the given amount of dominant colors an image +func getColorPalette(image string, amount int) ([]color.Color, error) { timestamp := time.Now().UnixMilli() - colors, error := color_thief.GetPaletteFromFile(image, 16, 0) + colors, error := color_thief.GetPaletteFromFile(image, amount, 0) if error == nil { - loggo.DebugTimed("generated color palette from image", timestamp, "image: "+image) + loggo.DebugTimed("generated color palette from image", timestamp, "image: "+image, "colors: "+strconv.Itoa(amount)) } return colors, error } diff --git a/internal/slideshow/slideshow.go b/internal/slideshow/slideshow.go index 1ab82e4..65b529a 100644 --- a/internal/slideshow/slideshow.go +++ b/internal/slideshow/slideshow.go @@ -13,6 +13,10 @@ import ( "git.velvettear.de/velvettear/slideshow/internal/watcher" ) +// currently set image +var image string + +// remember last shown image var previousImage string // start the slideshow @@ -23,7 +27,6 @@ func Start() { scaleImages := config.IsResolutionSet() for { var data []byte - var image string for { image = watcher.GetRandomImage() if image != previousImage { @@ -40,6 +43,10 @@ func Start() { data = tmp scaleTime = time.Since(scaleTimestamp) } + error := exportPalette() + if error != nil { + loggo.Error("encountered an error exporting the color palette for image", "image: "+image, error.Error()) + } if sleepTime > 0 { loggo.Debug("sleeping for " + strconv.FormatInt(sleepTime.Milliseconds(), 10) + "ms") time.Sleep(sleepTime) @@ -129,3 +136,8 @@ func setBackgroundPiped(data []byte) error { } return nil } + +// get currently shown image +func GetImage() string { + return image +}