Home

Tuesday, December 28, 2021

Python: Wallpaper-scroller - Entry 1 - Rough Gif Support

Python Side Project

-Wallpaper Scroller-


 I am still working on my RPG inventory system. But I've been too tired to think about it. So I was dinking around with a wallpaper scrolling script.


Here is a video of it working.

I show the gif playing function and the base function to set the wallpaper image. Gifs do not play true to duration / fps. Since the OS method I call to set the background appears to have a limit low tolerance for quick changes. A gif I tested at with 79 frames and a duration of 50 milliseconds didn't play nice with the script.


 

_______________________________________________________________

 

Brief:

Overall it is a very simple script. I used Pillow library to parse the gif frames, duration, and save them to a temporary folder so I could have a file path for windows to open. I can't say I like the current code, I might revisit it sometime.For now I'm going to refocus on the Text RPG modules.


Possible improvements:
  • support for higher frame rate gifs
  • altering stretch, tile, fit settings
  • add a tkinter tray interface


Code Snippet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import os # To create folders and save gif frames
import ctypes # To set the windows background image
import glob # To pull file contents of a directory
from PIL import Image # To parse gif data


def import_images( direct:str, fext: [ str ] ) -> { str : [ str ] }:
    """Takes a directory and a list of files with extension to include. Returns a dictionary with the extension as a key and a array of image names."""

    """Prime the dictionary with the { key(extension) : value(empty array) } """
    img_dict = { }
    for extension in fext:
        img_dict.update( { extension : [] } )
    
    """Use glob() to pull in all files of extension at path, clean the name string and append it to appropriate key : array."""
    for extension in fext:
        for filename in glob.glob( f'{ direct }\\*.{ extension }' ):
            file = filename.replace( f"{ direct }\\", "" )
            img_dict[extension].append( file )
    return img_dict


def set_background( path:str ) -> None:
    """Takes in a absolute path and call the OS to set background image."""
    ctypes.windll.user32.SystemParametersInfoW(
            20, # System wallpaper index
            0, # Buffer
            f"{ path }", # File Absolute Path
            0 # Final Buffer
        )


def unpack_gif( directory:str, image:str, temp:str="temp_frames" ) -> None:
    """Takes in a directory path, an image name.gif, and a new temp folder name. Then parses out the gif's frames into the temp folder at directory. Once a valid path is available set that background to path."""

    image_path = os.path.join(directory, image)
    with Image.open( image_path ) as im: # Open the gif with pillow

        temp_folder = temp # Name of temporary gif frames folder
        folder_path = os.path.join(directory, temp_folder)
        try:
            os.mkdir( folder_path ) # Create the temporary folder to hold the gifs frames
        except: pass
        
        frame_duration = im.info['duration'] # Get gif run length in milliseconds
        img_fps = ( ( frame_duration / im.n_frames ) / 1000 ) # Get the time per frame in milliseconds and convert it to seconds.

        for frame in range(im.n_frames): # Get the number of frames in the gif
            im.seek( frame ) # The current frame in for loop 0 - end_frame
            name = f'temp_gif_{frame}.png' # Create a name for the frame image
            path = os.path.join(folder_path, name)
            
            im.save( path, 'GIF' ) # Save the frame image to the temporary folder
            set_background( path ) # Now we have a path to set the background, call the set function
            time.sleep( img_fps * 10 ) # slow down to not congest the wallpaper assignment

credits and resources:

Code formatted via: <!-- http://hilite.me/ --!><!-- Python, monokai --!>
 
<!-- http://www.craftyfella.com/2010/01/syntax-highlighting-with-blogger-engine.html --!>
<!-- https://stackoverflow.com/questions/679189/formatting-code-snippets-for-blogging-on-blogger --!>
<!--  --!>
<!-- http://www.craftyfella.com/2010/01/syntax-highlighting-with-blogger-engine.html --!>
<!-- https://gogopdf.com/blog/Alex-Gorbatchev-And-gogopdf-Turn-Raw-Javascript-To-A-PDF-Service --!>

-END-

No comments:

Post a Comment

Conduct: Be nice and don't advertise or plug without adding value to the conversation.