Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# SPDX-FileCopyrightText: 2022 Tim C, written for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
"""
PyPortal winamp skin converter.
"""
import sys
import json
from PIL import Image, ImageDraw

# get input filename from terminal args
if len(sys.argv) >= 2:
input_filename = sys.argv[1]
else:
input_filename = "base.png"

# Opens a image in RGB mode
im = Image.open(input_filename)

newsize = (240, 320)

find_text_color_dict = {}

# scan pixels to get color counts
for i in range(8):
if im.getpixel((113, 26 + i)) in find_text_color_dict.keys():
find_text_color_dict[im.getpixel((113, 26 + i))] += 1
else:
find_text_color_dict[im.getpixel((113, 26 + i))] = 1
# print(find_text_color_dict)
lowest_pixel_count = None
text_color = None
highest_pixel_count = None

# scan pixel for backdrop color
back_drop_color = im.getpixel((120, 29))
for color in find_text_color_dict:
if not highest_pixel_count:
highest_pixel_count = find_text_color_dict[color]
text_color = color
elif highest_pixel_count < find_text_color_dict[color]:
highest_pixel_count = find_text_color_dict[color]
text_color = color

# print("backdrop: {}".format(back_drop_color))
time_color = text_color
config_data = {"text_color": text_color, "time_color": time_color}

find_text_color_dict = {}
for i in range(21):
if im.getpixel((65, 23 + i)) in find_text_color_dict.keys():
find_text_color_dict[im.getpixel((65, 23 + i))] += 1
else:
find_text_color_dict[im.getpixel((65, 23 + i))] = 1

# rectangle cutout for for current track title
cur_song_shape = ((112, 25), (265, 34))
img_draw = ImageDraw.Draw(im)
img_draw.rectangle(cur_song_shape, fill=back_drop_color)

# rectangle cutouts for clock display
time_shape_size = (9, 13)
time_shape_x_locs = (48, 60, 78, 90)

for x_loc in time_shape_x_locs:
_cur_time_shape_loc = (x_loc, 26)
_cur_time_shape = (
_cur_time_shape_loc,
(
_cur_time_shape_loc[0] + time_shape_size[0],
_cur_time_shape_loc[1] + time_shape_size[1],
),
)
img_draw.rectangle(_cur_time_shape, fill=back_drop_color)

# rectangle cutout for playlist display
playlist_shape_size = (244, 48)
playlist_shape_loc = (12, 257)
playlist_shape = (
playlist_shape_loc,
(
playlist_shape_loc[0] + playlist_shape_size[0],
playlist_shape_loc[1] + playlist_shape_size[1],
),
)

img_draw.rectangle(playlist_shape, fill=back_drop_color)

# write config json file
f = open(input_filename.replace(".png", "_config.json"), "w")
f.write(json.dumps(config_data))
f.close()

# resize to fit pyportal
im = im.resize(newsize)

# convert to indexed color
im = im.convert(mode="P", palette=Image.WEB)
# save output BMP file
im.save(input_filename.replace(".png", "_240x320.bmp"))
Binary file added PyPortal_Winamp_Player/base_240x320.bmp
Binary file not shown.
1 change: 1 addition & 0 deletions PyPortal_Winamp_Player/base_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"text_color": [0, 226, 0, 255], "time_color": [0, 226, 0, 255]}
124 changes: 124 additions & 0 deletions PyPortal_Winamp_Player/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# SPDX-FileCopyrightText: 2022 Tim C, written for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
"""
PyPortal winamp player
"""
import time
import sys
import storage
import board
import busio
import digitalio
import adafruit_touchscreen
import adafruit_sdcard
from winamp_helpers import WinampApplication

# which playlist to play
PLAYLIST_FILE = "playlist.json"

# which skin background to use
SKIN_IMAGE = "/base_240x320.bmp"

# skin configuration for color values
SKIN_CONFIG_FILE = "base_config.json"

# must wait at least this long between touch events
TOUCH_COOLDOWN = 0.5 # seconds

# display orientation. Must be 90 or 270.
ORIENTATION = 90

if ORIENTATION == 270:
# setup touch screen
ts = adafruit_touchscreen.Touchscreen(
board.TOUCH_YD,
board.TOUCH_YU,
board.TOUCH_XR,
board.TOUCH_XL,
calibration=((5200, 59000), (5800, 57000)),
size=(240, 320),
)
elif ORIENTATION == 90:
# setup touch screen
ts = adafruit_touchscreen.Touchscreen(
board.TOUCH_YU,
board.TOUCH_YD,
board.TOUCH_XL,
board.TOUCH_XR,
calibration=((5200, 59000), (5800, 57000)),
size=(240, 320),
)
else:
raise ValueError("ORIENTATION must be 90 or 270")

# Initializations for SDCard
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = digitalio.DigitalInOut(board.SD_CS)
sdcard = adafruit_sdcard.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
sys.path.append("/sd")

# debugging, print files that exist on SDCard
# print(os.listdir("/sd"))

# get reference to the display
display = board.DISPLAY

# set rotation
display.rotation = ORIENTATION

# Initialize WinampApplication helper class
winamp_application = WinampApplication(
playlist_file=PLAYLIST_FILE,
skin_image=SKIN_IMAGE,
skin_config_file=SKIN_CONFIG_FILE,
)

# Add the Group to the Display
display.show(winamp_application)

# previous iteration touch events
_previous_touch = None

# last time a touch occured
_previous_touch_time = 0

# main loop
while True:
# update winamp application
winamp_application.update()

# check for touch events
p = ts.touch_point
_now = time.monotonic()
# if touch cooldown time has elapsed
if _now >= _previous_touch_time + TOUCH_COOLDOWN:
# if there is a touch
if p and not _previous_touch:
# store the time to compare with next iteration
_previous_touch_time = _now
# if touch is on bottom half
if p[1] > 320 // 2:
# if touch is on right half
if p[0] >= 240 // 2:
winamp_application.next_track()

# if touch is on left half
else:
winamp_application.previous_track()
# if touch is on top half
elif p[1] <= 240 // 2:
# if currently playing song
if winamp_application.CURRENT_STATE == winamp_application.STATE_PLAYING:
print("pausing")
winamp_application.pause()

# if song is paused
else:
print("resuming")
winamp_application.resume()

# store previous touch event t compare with next iteration
_previous_touch = p
7 changes: 7 additions & 0 deletions PyPortal_Winamp_Player/playlist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"playlist": {
"files": [

]
}
}
Loading