|
| 1 | +# SPDX-FileCopyrightText: 2022 Tim C, written for Adafruit Industries |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: Unlicense |
| 4 | +""" |
| 5 | +PyPortal winamp skin converter. |
| 6 | +""" |
| 7 | +import sys |
| 8 | +import json |
| 9 | +from PIL import Image, ImageDraw |
| 10 | + |
| 11 | +# get input filename from terminal args |
| 12 | +if len(sys.argv) >= 2: |
| 13 | + input_filename = sys.argv[1] |
| 14 | +else: |
| 15 | + input_filename = "base.png" |
| 16 | + |
| 17 | +# Opens a image in RGB mode |
| 18 | +im = Image.open(input_filename) |
| 19 | + |
| 20 | +newsize = (240, 320) |
| 21 | + |
| 22 | +find_text_color_dict = {} |
| 23 | + |
| 24 | +# scan pixels to get color counts |
| 25 | +for i in range(8): |
| 26 | + if im.getpixel((113, 26 + i)) in find_text_color_dict.keys(): |
| 27 | + find_text_color_dict[im.getpixel((113, 26 + i))] += 1 |
| 28 | + else: |
| 29 | + find_text_color_dict[im.getpixel((113, 26 + i))] = 1 |
| 30 | +# print(find_text_color_dict) |
| 31 | +lowest_pixel_count = None |
| 32 | +text_color = None |
| 33 | +highest_pixel_count = None |
| 34 | + |
| 35 | +# scan pixel for backdrop color |
| 36 | +back_drop_color = im.getpixel((120, 29)) |
| 37 | +for color in find_text_color_dict: |
| 38 | + if not highest_pixel_count: |
| 39 | + highest_pixel_count = find_text_color_dict[color] |
| 40 | + text_color = color |
| 41 | + elif highest_pixel_count < find_text_color_dict[color]: |
| 42 | + highest_pixel_count = find_text_color_dict[color] |
| 43 | + text_color = color |
| 44 | + |
| 45 | +# print("backdrop: {}".format(back_drop_color)) |
| 46 | +time_color = text_color |
| 47 | +config_data = {"text_color": text_color, "time_color": time_color} |
| 48 | + |
| 49 | +find_text_color_dict = {} |
| 50 | +for i in range(21): |
| 51 | + if im.getpixel((65, 23 + i)) in find_text_color_dict.keys(): |
| 52 | + find_text_color_dict[im.getpixel((65, 23 + i))] += 1 |
| 53 | + else: |
| 54 | + find_text_color_dict[im.getpixel((65, 23 + i))] = 1 |
| 55 | + |
| 56 | +# rectangle cutout for for current track title |
| 57 | +cur_song_shape = ((112, 25), (265, 34)) |
| 58 | +img_draw = ImageDraw.Draw(im) |
| 59 | +img_draw.rectangle(cur_song_shape, fill=back_drop_color) |
| 60 | + |
| 61 | +# rectangle cutouts for clock display |
| 62 | +time_shape_size = (9, 13) |
| 63 | +time_shape_x_locs = (48, 60, 78, 90) |
| 64 | + |
| 65 | +for x_loc in time_shape_x_locs: |
| 66 | + _cur_time_shape_loc = (x_loc, 26) |
| 67 | + _cur_time_shape = ( |
| 68 | + _cur_time_shape_loc, |
| 69 | + ( |
| 70 | + _cur_time_shape_loc[0] + time_shape_size[0], |
| 71 | + _cur_time_shape_loc[1] + time_shape_size[1], |
| 72 | + ), |
| 73 | + ) |
| 74 | + img_draw.rectangle(_cur_time_shape, fill=back_drop_color) |
| 75 | + |
| 76 | +# rectangle cutout for playlist display |
| 77 | +playlist_shape_size = (244, 48) |
| 78 | +playlist_shape_loc = (12, 257) |
| 79 | +playlist_shape = ( |
| 80 | + playlist_shape_loc, |
| 81 | + ( |
| 82 | + playlist_shape_loc[0] + playlist_shape_size[0], |
| 83 | + playlist_shape_loc[1] + playlist_shape_size[1], |
| 84 | + ), |
| 85 | +) |
| 86 | + |
| 87 | +img_draw.rectangle(playlist_shape, fill=back_drop_color) |
| 88 | + |
| 89 | +# write config json file |
| 90 | +f = open(input_filename.replace(".png", "_config.json"), "w") |
| 91 | +f.write(json.dumps(config_data)) |
| 92 | +f.close() |
| 93 | + |
| 94 | +# resize to fit pyportal |
| 95 | +im = im.resize(newsize) |
| 96 | + |
| 97 | +# convert to indexed color |
| 98 | +im = im.convert(mode="P", palette=Image.WEB) |
| 99 | +# save output BMP file |
| 100 | +im.save(input_filename.replace(".png", "_240x320.bmp")) |
0 commit comments