i'm working on a big rgb matrix project using the espn API to get data for tracking various sports teams. since it's an rgb matrix it makes sense to display the team logos. however, there are a lot of teams across all of the leagues and images for rgb matrices have to be just so. this part of the project was really intimidating.
however, as luck would have it, the espn API includes links to excellent .PNG image files for each team. i wrote a python script that creates folders on your computer for each set of images, downloads the images, names them to match the team abbreviation in the API, resizes them, adds gamma correction from the image correction for led matrices guide, spits out a properly formatted bitmap file and deletes the original .PNG image
import wget from PIL import Image import os import json import ssl import requests import math ssl._create_default_https_context = ssl._create_unverified_context home_directory = r"YOUR-DIRECTORY-HERE" mlb_folder_name = "mlb_logos" mlb_folder = os.path.join(home_directory, mlb_folder_name) os.makedirs(mlb_folder) nfl_folder_name = "nfl_logos" nfl_folder = os.path.join(home_directory, nfl_folder_name) os.makedirs(nfl_folder) nhl_folder_name = "nhl_logos" nhl_folder = os.path.join(home_directory, nhl_folder_name) os.makedirs(nhl_folder) nba_folder_name = "nba_logos" nba_folder = os.path.join(home_directory, nba_folder_name) os.makedirs(nba_folder) mls_folder_name = "mls_logos" mls_folder = os.path.join(home_directory, mls_folder_name) os.makedirs(mls_folder) size = (32, 32) mlb_data = ("https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/teams") nfl_data = ("https://site.api.espn.com/apis/site/v2/sports/football/nfl/teams") nhl_data = ("https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/teams") nba_data = ("https://site.api.espn.com/apis/site/v2/sports/basketball/nba/teams") mls_data = ("https://site.api.espn.com/apis/site/v2/sports/soccer/usa.1/teams") GAMMA = 2.6 def process(img, output_8_bit=False, passthrough=None): """Given a color image filename, load image and apply gamma correction and error-diffusion dithering while quantizing to 565 color resolution. If output_8_bit is True, image is reduced to 8-bit paletted mode after quantization/dithering. If passthrough (a list of 3-tuple RGB values) is provided, dithering won't be applied to colors in the provided list, they'll be quantized only (allows areas of the image to remain clean and dither-free). Writes a BMP file with the same name plus '-processed' and .BMP extension. """ err_next_pixel = (0, 0, 0) # Error diffused to the right err_next_row = [(0, 0, 0) for _ in range(img.size[0])] # " diffused down for row in range(img.size[1]): for column in range(img.size[0]): pixel = img.getpixel((column, row)) want = (math.pow(pixel[0] / 255.0, GAMMA) * 31.0, # Gamma and math.pow(pixel[1] / 255.0, GAMMA) * 63.0, # quantize math.pow(pixel[2] / 255.0, GAMMA) * 31.0) # to 565 res if pixel in passthrough: # In passthrough list? got = (pixel[0] >> 3, # Take color literally, pixel[1] >> 2, # though quantized pixel[2] >> 3) else: got = (min(max(int(err_next_pixel[0] * 0.5 + # Diffuse err_next_row[column][0] * 0.25 + # from want[0] + 0.5), 0), 31), # prior XY min(max(int(err_next_pixel[1] * 0.5 + err_next_row[column][1] * 0.25 + want[1] + 0.5), 0), 63), min(max(int(err_next_pixel[2] * 0.5 + err_next_row[column][2] * 0.25 + want[2] + 0.5), 0), 31)) err_next_pixel = (want[0] - got[0], want[1] - got[1], want[2] - got[2]) err_next_row[column] = err_next_pixel rgb565 = ((got[0] << 3) | (got[0] >> 2), # Quantized result (got[1] << 2) | (got[1] >> 4), # after dither (got[2] << 3) | (got[2] >> 2)) img.putpixel((column, row), rgb565) # Put pixel back in image if output_8_bit: img = img.convert('P', palette=Image.ADAPTIVE) # This is a set of color values where error diffusion dithering won't be # applied (is still calculated for subsequent pixels, but not applied). # Here it's set up for primary colors, so these always appear unfettered # in output images. PASSTHROUGH = ((0, 0, 0), (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255), (0, 0, 255), (255, 0, 255), (255, 255, 255)) def logo_to_bitmap(data, folder, logo_num): response = requests.get(data) the_json = response.json() for i in range(len(the_json['sports'][0]['leagues'][0]['teams'])): url = the_json['sports'][0]['leagues'][0]['teams'][i]['team']['logos'][logo_num]['href'] filename = str(the_json['sports'][0]['leagues'][0]['teams'][i]['team']['abbreviation']) + ".png" file = os.path.join(folder, filename) converted_filename = str(the_json['sports'][0]['leagues'][0]['teams'][i]['team']['abbreviation']) + ".bmp" converted_file = os.path.join(folder, converted_filename) print(url) testfile = wget.download(url, file) img = Image.open(file) img.thumbnail(size) img1 = img.convert("RGB") process(img1, True, PASSTHROUGH) img1.save(converted_file) os.remove(file) logo_to_bitmap(mlb_data, mlb_folder, 0) logo_to_bitmap(nfl_data, nfl_folder, 0) logo_to_bitmap(nhl_data, nhl_folder, 0) logo_to_bitmap(nba_data, nba_folder, 0) logo_to_bitmap(mls_data, mls_folder, 1)