├── model ├── heart.png ├── kali.png ├── windows.png └── red-cloud.png ├── screenshot ├── screenshot.png ├── screenshot1.png ├── screenshot2.png ├── screenshot3.png ├── screenshot4.png └── screenshot5.png ├── README.md ├── change_wallpaper.py └── generate_wallpaper.py /model/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/model/heart.png -------------------------------------------------------------------------------- /model/kali.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/model/kali.png -------------------------------------------------------------------------------- /model/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/model/windows.png -------------------------------------------------------------------------------- /model/red-cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/model/red-cloud.png -------------------------------------------------------------------------------- /screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/screenshot/screenshot.png -------------------------------------------------------------------------------- /screenshot/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/screenshot/screenshot1.png -------------------------------------------------------------------------------- /screenshot/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/screenshot/screenshot2.png -------------------------------------------------------------------------------- /screenshot/screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/screenshot/screenshot3.png -------------------------------------------------------------------------------- /screenshot/screenshot4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/screenshot/screenshot4.png -------------------------------------------------------------------------------- /screenshot/screenshot5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tachyglossues/wallpaper-process-wordcloud/HEAD/screenshot/screenshot5.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wallpaper-process-wordcloud 2 | it's a script that generates a gnome wallpaper with the pc processes in a word cloud that looks like a minimalist image. 3 | ![](https://github.com/tachyglossues/wallpaper-process-wordcloud/blob/main/screenshot/screenshot2.png) 4 | 5 | 6 | ## Setup 7 | 8 | * Clone this repo. 9 | 10 | ``` 11 | git clone https://github.com/tachyglossues/wallpaper-process-wordcloud.git 12 | ``` 13 | 14 | * Run. 15 | 16 | ``` 17 | cd wallpaper-process-wordcloud 18 | python3 generateWallpaper.py 19 | ``` 20 | ## Install : 21 | 22 | ``` 23 | pip install wordcloud 24 | pip install PIL 25 | pip install screeninfo 26 | pip install scipy 27 | pip install numpy 28 | pip install matplolib 29 | pip install psutil 30 | ``` 31 | -------------------------------------------------------------------------------- /change_wallpaper.py: -------------------------------------------------------------------------------- 1 | import platform 2 | import sys 3 | 4 | def set_wallpaper(image_path): 5 | os_name = platform.system() 6 | 7 | if os_name == 'Windows': 8 | try: 9 | import ctypes 10 | ctypes.windll.user32.SystemParametersInfoW(20, 0, image_path, 3) 11 | except ImportError: 12 | print("Error: Unable to import 'ctypes' library. Run 'pip install ctypes' in your shell and try again.") 13 | sys.exit(1) 14 | 15 | elif os_name == 'Darwin': 16 | try: 17 | import osascript 18 | script = f''' 19 | tell application "Finder" 20 | set desktop picture to POSIX file "{image_path}" 21 | end tell 22 | ''' 23 | osascript.run(script) 24 | except ImportError: 25 | print("Error: Unable to import 'osascript' library. Run 'pip install osascript' in your shell and try again.") 26 | sys.exit(1) 27 | 28 | elif os_name == 'Linux': 29 | try: 30 | import subprocess 31 | command = f"sudo gsettings set org.gnome.desktop.background picture-uri file://{image_path}" 32 | subprocess.call(command, shell=True) 33 | except ImportError: 34 | print("Error: Unable to import 'subprocess' library. Run 'pip install subprocess' in your shell and try again.") 35 | sys.exit(1) 36 | 37 | else: 38 | print(f"Error: Operating system {os_name} is not supported for changing wallpaper.") 39 | sys.exit(1) 40 | 41 | -------------------------------------------------------------------------------- /generate_wallpaper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from scipy.ndimage import gaussian_gradient_magnitude 5 | import psutil 6 | from PIL import Image 7 | from wordcloud import WordCloud, ImageColorGenerator 8 | import time 9 | from screeninfo import get_monitors 10 | from change_wallpaper import set_wallpaper 11 | 12 | 13 | 14 | 15 | 16 | def get_running_processes(): 17 | command_dict = {} 18 | for process in psutil.process_iter(['name', 'cpu_percent', 'memory_percent']): 19 | command = process.info['name'].split('/')[0].replace(".exe", "") 20 | cpu = process.info['cpu_percent'] 21 | mem = process.info['memory_percent'] 22 | if command in command_dict: 23 | command_dict[command][0] += cpu 24 | command_dict[command][1] += mem 25 | else: 26 | command_dict[command] = [cpu, mem] 27 | resource_dict = {} 28 | for command, [cpu, mem] in command_dict.items(): 29 | resource_dict[command] = (cpu + mem)*10 30 | return resource_dict 31 | 32 | 33 | 34 | 35 | def generate_wallpaper(): 36 | if model != 0: 37 | wallpaper_coloring = np.array(Image.open(imagesselect)) 38 | wallpaper_coloring = wallpaper_coloring[::2, ::2] 39 | wallpaper_mask = wallpaper_coloring.copy() 40 | wallpaper_mask[wallpaper_mask.sum(axis=2) == 0] = 255 41 | edges = np.mean([gaussian_gradient_magnitude(wallpaper_coloring[:, :, i] / 255.0, 2)for i in range(2)],axis=0,) 42 | wallpaper_coloring[edges > 1] = 255 43 | 44 | if color_ther ==2: 45 | wc = WordCloud(mask=wallpaper_mask,background_color = background_colorg ,max_words=700,relative_scaling=0.4 ,repeat=True).generate_from_frequencies(get_running_processes()) 46 | image_colors = ImageColorGenerator(wallpaper_coloring) 47 | wc.recolor(color_func=image_colors) 48 | else: 49 | wc = WordCloud(mask=wallpaper_mask, background_color = background_colorg ,max_words=700,relative_scaling=0.4 ,repeat=True, colormap=chosen_palette).generate_from_frequencies(get_running_processes()) 50 | 51 | wc.to_file("temp.png") 52 | wordcloud = Image.open("temp.png") 53 | wallpaper = Image.new("RGB", (width, height), color = background_colorg) 54 | wallpaper.paste(wordcloud,(int((width-wordcloud.size[0])/2),int((height - wordcloud.size[1])/ 2),),) 55 | wallpaper.save("wallpaper.png") 56 | else: 57 | wc = WordCloud(max_words=700,background_color = background_colorg,repeat=True,colormap=chosen_palette,width=width,height=height).generate_from_frequencies(get_running_processes()) 58 | wc.to_file("wallpaper.png") 59 | print("wallpaper generated") 60 | 61 | 62 | 63 | 64 | def is_valid_hex_color(color): 65 | if len(color)<2 or len(color)>7: 66 | return (False,None) 67 | if color[0] != '#': 68 | color = "#" + color 69 | if (lencolor:=len(color)) == 4 or lencolor == 7 : 70 | try: 71 | int(color[1:], 16) 72 | return (True,color) 73 | except ValueError: 74 | return (False,None) 75 | 76 | 77 | infinity = False 78 | color_palettes = ['Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'winter', 'winter_r'] 79 | current_dir = os.path.dirname(__file__) if "__file__" in locals() else os.getcwd() 80 | 81 | width, height = None, None 82 | for monitor in get_monitors(): 83 | if monitor.x == 0 and monitor.y == 0: 84 | width = int(monitor.width) 85 | height = int(monitor.height) 86 | break 87 | 88 | while True: 89 | 90 | try: 91 | mode = int(input("Choose the mode of operation of the program:\n- 0: predefined mode (can't change your wallpaper but will generate 'Wallpaper.png') \n- 1: customizable mode\n\nEnter the number corresponding to your choice:\t")) 92 | if mode in [0,1]: 93 | break 94 | print("\nError: please enter an integer between 0 and 1.\n") 95 | except ValueError: 96 | print("\nError: please enter an integer between 0 and 1.\n") 97 | 98 | 99 | 100 | 101 | 102 | 103 | if mode == 1: 104 | print("\n\n\n\nWelcome to the customizable mode\n\n") 105 | while True: 106 | try: 107 | model = int(input("Choose the type of word cloud :\n- 0: on the whole screen :\n- 1: a pre-installed model :\n- 2: a custom model that you have added in ./temp/ Enter the number corresponding to your choice :\t")) 108 | if model in [0,1,2]: 109 | break 110 | print("\nError: please enter an integer between 0 and 2\n") 111 | except ValueError: 112 | print("\nError: please enter an integer between 0 and 2\n") 113 | print("\n"*7) 114 | if model != 0: 115 | if model == 2: 116 | folder_path = "temp/" 117 | else: 118 | folder_path = "model/" 119 | files = os.listdir(folder_path) 120 | images = [f for f in files if f.endswith('.jpg') or f.endswith('.png') or f.endswith('.jpeg') ] 121 | if len(images) == 0: 122 | print("Error: no image file found in the folder so the wallpaper will not have a template!!!") 123 | model = 0 124 | time.sleep(3) 125 | else: 126 | 127 | for i, image in enumerate(images): 128 | i = str(i+1) 129 | print(i + ': ' + image) 130 | try: 131 | chosen_number = int(input("Choose an image by entering its number: ")) 132 | chosen_image = images[chosen_number-1] 133 | except ValueError: 134 | print("Error: please enter a number from the list.") 135 | print("Your choice " + chosen_image) 136 | imagesselect = folder_path + chosen_image 137 | print("\n"*7) 138 | while True: 139 | try: 140 | print("Choose the color palette of the word cloud:\n - 0: for a random color palette\n - 1: to choose from a pre-defined list of color palettes") 141 | permitted_value = [0,1] 142 | if model in [1,2]: 143 | print("- 2: for the model's color palette") 144 | permitted_value.append(2) 145 | color_ther = int(input("\nEnter the number corresponding to your choice:\n")) 146 | if color_ther in permitted_value: 147 | break 148 | print("Error: value must be an allowed integer") 149 | except ValueError: 150 | print("Error: value must be an allowed integer") 151 | chosen_palette = "The model's one" 152 | if color_ther == 0: 153 | chosen_palette = np.random.choice(color_palettes) 154 | time.sleep(1) 155 | elif color_ther == 1: 156 | for i, palette in enumerate(color_palettes): 157 | i = str(i+1) 158 | print('{:<3}'.format(i + ':' + palette), end=(25-(len(palette)+len(i)))*' ') 159 | if int(i) % 7 == 0: 160 | print("") 161 | try: 162 | chosen_number = int(input("\nChoose a palette by entering its number: ")) 163 | chosen_palette = color_palettes[chosen_number-1] 164 | except ValueError: 165 | print("Error: please enter a number from the list.") 166 | print("Selected color palette: " + chosen_palette) 167 | time.sleep(1) 168 | 169 | print("\n"*7) 170 | background_colorg = input("Enter a hexadecimal color for the background of the image (e.g. #000 -> black or #ffffff -> white): ") 171 | try: 172 | while not is_valid_hex_color(background_colorg)[0]: 173 | print("Invalid hexadecimal color.") 174 | background_colorg = input("Enter a hexadecimal color for the background of the image (e.g. #000 -> black or #ffffff -> white): ") 175 | except ValueError: 176 | print("Invalid hexadecimal color.") 177 | 178 | background_colorg = is_valid_hex_color(background_colorg)[1] 179 | print("\n"*7) 180 | 181 | while True: 182 | change_wallpaper = input("Do you want the program to automatically change your wallpaper? (yes/no): ").lower().replace(" ","") 183 | if change_wallpaper in ["true","yes", "y"]: 184 | change_wallpaper = True 185 | break 186 | elif change_wallpaper in ["false","no", "n"]: 187 | change_wallpaper = False 188 | break 189 | print("Invalid answer") 190 | 191 | print("\n"*7) 192 | 193 | if change_wallpaper: 194 | while True: 195 | infinity= input("Do you want the wallpaper to be updated every X seconds? (yes/no): ").lower().replace(" ","") 196 | if infinity in ["true","yes", "y"]: 197 | infinity = True 198 | print("\n"*7) 199 | break 200 | elif infinity in ["false","no", "n"]: 201 | infinity = False 202 | break 203 | else : 204 | print("Invalid answer") 205 | 206 | 207 | if infinity: 208 | while True: 209 | try: 210 | delay = int(str(input("What delay in minutes between each wallpaper update (minimum 5min)? ")).replace("min","").replace(" ","").replace("minute","").replace("s","")) 211 | if delay > 4: 212 | delay *= 60 213 | break 214 | else: 215 | print("Error: delay must be greater than or equal to 5 minutes.") 216 | except ValueError: 217 | print("Error: delay must be greater than or equal to 5 minutes.") 218 | print("\n\n\n\n\nThe images will be generated") 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | start_time = time.time() 229 | generate_wallpaper() 230 | if change_wallpaper: 231 | set_wallpaper("Wallpaper.png") 232 | while True: 233 | end_time = time.time() 234 | execution_time = end_time - start_time 235 | time.sleep(delay-execution_time) 236 | start_time = time.time() 237 | generate_wallpaper() 238 | set_wallpaper("Wallpaper.png") 239 | else: 240 | print("\n\n\n\n\n\nWelcome to the predefined mode") 241 | while True: 242 | try: 243 | presets = int(input("Choose the model to use:\n- 0: Heart\n- 1: Windows\n- 2: Full Screen\n- 3: Kali\n\nEnter the number corresponding to your choice:\t")) 244 | if presets in [0,1,2,3]: 245 | break 246 | print("\nError: please enter an integer between 0 and 3.\n") 247 | except ValueError: #if the user's input is not an integer 248 | print("\nError: please enter an integer between 0 and 3.\n") 249 | 250 | if presets == 0: 251 | model,imagesselect, color_ther,background_colorg = 1, "model/heart.png", 2, "black" 252 | elif presets == 1: 253 | model,imagesselect, color_ther,background_colorg = 1, "model/windows.png", 2, "black" 254 | elif presets == 2: 255 | background_colorg, chosen_palette, model = None, np.random.choice(color_palettes), 0 256 | else: 257 | model,imagesselect, color_ther,background_colorg = 1, "model/dragon.png", 2, "black" 258 | print("the image will be generated\n\n") 259 | generate_wallpaper() 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | --------------------------------------------------------------------------------