Batch base64 encode PNGs in Python 3 for use in CSS.

I wrote a simple Python 3 script to base64 encode a series of PNG images for use in CSS, or whatever. If you’re learning Python try adding file output or even go a step further and generate the CSS lines. If you’re here I will assume you are wanting these for CSS but if not, here is an example of using base64 encoded images in CSS if you’re curious.

This script can be ran at the console, as a Python import, or simply as a script.

import os
import sys
import base64

def get_image_base64(base_image_path, image_types=['png']):
    """
    get_image_base64(base_image_path, image_types=['png']) -> dict
    Converts a folder list of images to base64.

    args:
        base_image_path = String path to files. Default 'png'
        image_types     = List of extension type to process.

    return -> Dict
    """
    encoded_strings = {}

    if os.path.exists(base_image_path):
        try:
            for img in os.listdir(base_image_path):
                
                # Only get images we care about.
                if os.path.splitext(img)[-1].replace('.','').lower() not in image_types:
                    continue
                
                # Set up the dict.                
                if img not in encoded_strings:
                    encoded_strings[img]=None
                # Get the image's full path.
                image_path = os.path.join(base_image_path,img)
                # Read and encode.
                with open(image_path, "rb") as stream:
                    raw = stream.read()
                    inc = base64.b64encode(raw)
                    encoded_strings[img]=inc
                    
        except Exception as e:
            print(e)
                
        return encoded_strings
    else:
        print ('%s not found.' %base_image_path)


# ==========================================================
# MAIN
"""
Use as Pyhton 3+ import.
Run as script.
Run from terminal: C:\> python img2base64 c:/images png,jpg
C. Nichols https://www.darkartistry.com/
"""
# ==========================================================
if __name__ in '__main__':
    """
    Exercises:
        Create a function to write results to disk.
        Add getopt and add an output file param.
    """

    image_filter = [] # Add a filter if you need to or alter the defaults in the function directly.

    script_base_path = '' # Set the path to images here to override interactive console run.
    #script_base_path = r'C:\pyprod\prod_web\static\images'
     
    img_path = None
    arg_path = None
    arg_filter = None

    # Determine if this script is executed from the console.
    # ======================================================
    # Run as script.
    # ======================================================
    if script_base_path:
        
        if len(image_filter) > 0:
            encoded = get_image_base64(script_base_path,image_types=image_filter)
        else:
            encoded = get_image_base64(script_base_path)

    # ======================================================
    # Run as interactive console app.
    # ======================================================
    else:

        usage = '\n\nUsage:\n\n img2base64 path_to_images png,gif\n\n Path is required.\n Comma delimited list, no spaces, of extensions is optional. Default is png.'
        argc = len(sys.argv)

        if argc == 1: print ('Too few arguments! This program requires at least a path and optional extensions to process.%s'%usage)
        if argc > 3: print ('Too many arguments! This program requires path and optional extensions to process.%s'%usage)

        if argc == 2:
            
            prog,arg_path = sys.argv
            print ('running interactively at %s'  %arg_path)
            encoded = get_image_base64(arg_path)
            
        if argc == 3:
            
            prog,arg_path,arg_filter = sys.argv
            arg_filter = [i.strip().lower() for i in arg_filter.split(',')]

            print ('running interactively at %s with filter %s'  %(arg_path,arg_filter))
            encoded = get_image_base64(arg_path, image_types=arg_filter)

    # Do something with the output, write to file, whatever...
    for img_name,enc_string in encoded.items():
        if enc_string:
            print ('\n', img_name, '->', enc_string)
        else:
            print ('\n', img_name, '-> Failed')