aboutsummaryrefslogtreecommitdiff
path: root/pywal/backends
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-09-12 11:29:21 +0000
committerFuwn <[email protected]>2024-09-12 11:36:10 +0000
commitd487f5e5cb22e58e5ec164e20168b39a75ca39e8 (patch)
treeadf8120847661c79a121848351c304507aeb7899 /pywal/backends
parentfeat: initial release (diff)
downloadpywal.nix-d487f5e5cb22e58e5ec164e20168b39a75ca39e8.tar.xz
pywal.nix-d487f5e5cb22e58e5ec164e20168b39a75ca39e8.zip
feat: more backends
Diffstat (limited to 'pywal/backends')
-rw-r--r--pywal/backends/__init__.py0
-rw-r--r--pywal/backends/colorthief.py79
-rw-r--r--pywal/backends/colorz.py60
-rw-r--r--pywal/backends/wal.py105
4 files changed, 244 insertions, 0 deletions
diff --git a/pywal/backends/__init__.py b/pywal/backends/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pywal/backends/__init__.py
diff --git a/pywal/backends/colorthief.py b/pywal/backends/colorthief.py
new file mode 100644
index 0000000..f1d52f7
--- /dev/null
+++ b/pywal/backends/colorthief.py
@@ -0,0 +1,79 @@
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+"""
+Generate a colorscheme using ColorThief.
+"""
+
+import logging
+import sys
+
+try:
+ from colorthief import ColorThief
+
+except ImportError:
+ logging.error("ColorThief wasn't found on your system.")
+ logging.error("Try another backend. (wal --backend)")
+ sys.exit(1)
+
+from .. import util
+
+
+def gen_colors(img):
+ """Loop until 16 colors are generated."""
+ color_cmd = ColorThief(img).get_palette
+
+ for i in range(0, 10, 1):
+ raw_colors = color_cmd(color_count=8 + i)
+
+ if len(raw_colors) >= 8:
+ break
+
+ if i == 10:
+ logging.error("ColorThief couldn't generate a suitable palette.")
+ sys.exit(1)
+
+ return [util.rgb_to_hex(color) for color in raw_colors]
+
+
+def adjust(cols, light):
+ """Create palette."""
+ cols.sort(key=util.rgb_to_yiq)
+ raw_colors = [*cols, *cols]
+
+ if light:
+ raw_colors[0] = util.lighten_color(cols[0], 0.90)
+ raw_colors[7] = util.darken_color(cols[0], 0.75)
+
+ else:
+ for color in raw_colors:
+ color = util.lighten_color(color, 0.40)
+
+ raw_colors[0] = util.darken_color(cols[0], 0.80)
+ raw_colors[7] = util.lighten_color(cols[0], 0.60)
+
+ raw_colors[8] = util.lighten_color(cols[0], 0.20)
+ raw_colors[15] = raw_colors[7]
+
+ return raw_colors
+
+
+def get(img, light=False):
+ """Get colorscheme."""
+ cols = gen_colors(img)
+ return adjust(cols, light)
diff --git a/pywal/backends/colorz.py b/pywal/backends/colorz.py
new file mode 100644
index 0000000..f05e534
--- /dev/null
+++ b/pywal/backends/colorz.py
@@ -0,0 +1,60 @@
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+"""
+Generate a colorscheme using Colorz.
+"""
+import logging
+import sys
+
+try:
+ import colorz
+
+except ImportError:
+ logging.error("colorz wasn't found on your system.")
+ logging.error("Try another backend. (wal --backend)")
+ sys.exit(1)
+
+from .. import colors
+from .. import util
+
+
+def gen_colors(img):
+ """Generate a colorscheme using Colorz."""
+ # pylint: disable=not-callable
+ raw_colors = colorz.colorz(img, n=6, bold_add=0)
+ return [util.rgb_to_hex([*color[0]]) for color in raw_colors]
+
+
+def adjust(cols, light):
+ """Create palette."""
+ raw_colors = [cols[0], *cols, "#FFFFFF", "#000000", *cols, "#FFFFFF"]
+
+ return colors.generic_adjust(raw_colors, light)
+
+
+def get(img, light=False):
+ """Get colorscheme."""
+ cols = gen_colors(img)
+
+ if len(cols) < 6:
+ logging.error("colorz failed to generate enough colors.")
+ logging.error("Try another backend or another image. (wal --backend)")
+ sys.exit(1)
+
+ return adjust(cols, light)
diff --git a/pywal/backends/wal.py b/pywal/backends/wal.py
new file mode 100644
index 0000000..883abb6
--- /dev/null
+++ b/pywal/backends/wal.py
@@ -0,0 +1,105 @@
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+"""
+Generate a colorscheme using imagemagick.
+"""
+
+import logging
+import re
+import shutil
+import subprocess
+import sys
+
+from .. import util
+
+
+def imagemagick(color_count, img, magick_command):
+ """Call Imagemagick to generate a scheme."""
+ flags = ["-resize", "25%", "-colors", str(color_count), "-unique-colors", "txt:-"]
+ img += "[0]"
+
+ return subprocess.check_output([*magick_command, img, *flags]).splitlines()
+
+
+def has_im():
+ """Check to see if the user has im installed."""
+ if shutil.which("magick"):
+ return ["magick"]
+
+ if shutil.which("convert"):
+ return ["convert"]
+
+ logging.error("Imagemagick wasn't found on your system.")
+ logging.error("Try another backend. (wal --backend)")
+ sys.exit(1)
+
+
+def gen_colors(img):
+ """Format the output from imagemagick into a list
+ of hex colors."""
+ magick_command = has_im()
+
+ for i in range(0, 20, 1):
+ raw_colors = imagemagick(16 + i, img, magick_command)
+
+ if len(raw_colors) > 16:
+ break
+
+ if i == 19:
+ logging.error("Imagemagick couldn't generate a suitable palette.")
+ sys.exit(1)
+
+ else:
+ logging.warning("Imagemagick couldn't generate a palette.")
+ logging.warning("Trying a larger palette size %s", 16 + i)
+
+ return [re.search("#.{6}", str(col)).group(0) for col in raw_colors[1:]]
+
+
+def adjust(colors, light):
+ """Adjust the generated colors and store them in a dict that
+ we will later save in json format."""
+ raw_colors = colors[:1] + colors[8:16] + colors[8:-1]
+
+ # Manually adjust colors.
+ if light:
+ for color in raw_colors:
+ color = util.saturate_color(color, 0.5)
+
+ raw_colors[0] = util.lighten_color(colors[-1], 0.85)
+ raw_colors[7] = colors[0]
+ raw_colors[8] = util.darken_color(colors[-1], 0.4)
+ raw_colors[15] = colors[0]
+
+ else:
+ # Darken the background color slightly.
+ if raw_colors[0][1] != "0":
+ raw_colors[0] = util.darken_color(raw_colors[0], 0.40)
+
+ raw_colors[7] = util.blend_color(raw_colors[7], "#EEEEEE")
+ raw_colors[8] = util.darken_color(raw_colors[7], 0.30)
+ raw_colors[15] = util.blend_color(raw_colors[15], "#EEEEEE")
+
+ return raw_colors
+
+
+def get(img, light=False):
+ """Get colorscheme."""
+ colors = gen_colors(img)
+ return adjust(colors, light)