convert_winamp_skin.py
  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  if "-t" in sys.argv or "--titano" in sys.argv:
 18      newsize = (320, 480)
 19  else:
 20      newsize = (240, 320)
 21  
 22  # Opens a image in RGB mode
 23  im = Image.open(input_filename)
 24  
 25  
 26  
 27  find_text_color_dict = {}
 28  
 29  # scan pixels to get color counts
 30  for i in range(8):
 31      if im.getpixel((113, 26 + i)) in find_text_color_dict.keys():
 32          find_text_color_dict[im.getpixel((113, 26 + i))] += 1
 33      else:
 34          find_text_color_dict[im.getpixel((113, 26 + i))] = 1
 35  # print(find_text_color_dict)
 36  lowest_pixel_count = None
 37  text_color = None
 38  highest_pixel_count = None
 39  
 40  # scan pixel for backdrop color
 41  back_drop_color = im.getpixel((120, 29))
 42  for color in find_text_color_dict:
 43      if not highest_pixel_count:
 44          highest_pixel_count = find_text_color_dict[color]
 45          text_color = color
 46      elif highest_pixel_count < find_text_color_dict[color]:
 47          highest_pixel_count = find_text_color_dict[color]
 48          text_color = color
 49  
 50  # print("backdrop: {}".format(back_drop_color))
 51  time_color = text_color
 52  config_data = {"text_color": text_color, "time_color": time_color}
 53  
 54  find_text_color_dict = {}
 55  for i in range(21):
 56      if im.getpixel((65, 23 + i)) in find_text_color_dict.keys():
 57          find_text_color_dict[im.getpixel((65, 23 + i))] += 1
 58      else:
 59          find_text_color_dict[im.getpixel((65, 23 + i))] = 1
 60  
 61  # rectangle cutout for for current track title
 62  cur_song_shape = ((112, 25), (265, 34))
 63  img_draw = ImageDraw.Draw(im)
 64  img_draw.rectangle(cur_song_shape, fill=back_drop_color)
 65  
 66  # rectangle cutouts for clock display
 67  time_shape_size = (9, 13)
 68  time_shape_x_locs = (48, 60, 78, 90)
 69  
 70  for x_loc in time_shape_x_locs:
 71      _cur_time_shape_loc = (x_loc, 26)
 72      _cur_time_shape = (
 73          _cur_time_shape_loc,
 74          (
 75              _cur_time_shape_loc[0] + time_shape_size[0],
 76              _cur_time_shape_loc[1] + time_shape_size[1],
 77          ),
 78      )
 79      img_draw.rectangle(_cur_time_shape, fill=back_drop_color)
 80  
 81  # rectangle cutout for playlist display
 82  playlist_shape_size = (244, 48)
 83  playlist_shape_loc = (12, 257)
 84  playlist_shape = (
 85      playlist_shape_loc,
 86      (
 87          playlist_shape_loc[0] + playlist_shape_size[0],
 88          playlist_shape_loc[1] + playlist_shape_size[1],
 89      ),
 90  )
 91  
 92  img_draw.rectangle(playlist_shape, fill=back_drop_color)
 93  
 94  # write config json file
 95  f = open(input_filename.replace(".png", "_config.json"), "w")
 96  f.write(json.dumps(config_data))
 97  f.close()
 98  
 99  # resize to fit pyportal
100  im = im.resize(newsize)
101  
102  # convert to indexed color
103  im = im.convert(mode="P", palette=Image.WEB)
104  # save output BMP file
105  im.save(input_filename.replace(".png", "_{}x{}.bmp".format(newsize[0], newsize[1])))