見出し画像

シャニマスのデジタルフォトフレームを作る③ ~画像収集・カレンダー化~

前回のシャニマスのデジタルフォトフレーム作成に引き続き以下のような機能を実装しました。

  • スクレイピングによって今までの画像を一挙に獲得

  • psrとpssrはタップしたら私服とステージ衣装が切り替わる

  • 現在の月を取得して、その月にリリースされた画像を表示

  • ついでに現在時刻も表示して卓上カレンダー+時計化

スクレイピングによる画像取得

PSSR、演出最高!
しかし、SRやS-SSRにもいっぱいいいイラストがあるんだよな…
・・・
スクレイピングで画像を一気にダウンロードすることにしました。
参考↓

たくさんサーバーアクセスしてごめんなさい!

これで画像は手に入ったのですが、後の実装(月に合わせた表示、タップしたらpアイドルの画像切り替え)のために、ファイル名を全て変換しました。
ファイル名は以下の通り
YYMMDD-n-xxxxm.jpg (YYMMDD: リリース年月日, n: アイドルの通し番号①真乃~㉘はるき, xxxx: psr, ssr, psssr, ssssrのいずれか, m: pカードに関してはさらに1: 私服, 2: ステージ衣装)
1000枚以上のカードに対してリネームしました。(愛があればなんでもする)

無心

カレンダー・時計化

ラズパイでデジタルサイネージを作ったいくつかのサイトを参考に

タップしたら動画が流れるのではなく、psrの私服とステージ衣装が切り替わるようにして、画像の取得は現在の月と同じリリース日の画像を選ぶようにして、
前回のコードを改変して以下のようになりました。

import sys
import pygame
import os
import numpy as np
import random
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE, K_j, MOUSEBUTTONDOWN
from datetime import datetime

pygame.init()
infoObject = pygame.display.Info()
SURFACE = pygame.display.set_mode((infoObject.current_w, infoObject.current_h), pygame.FULLSCREEN)
print(infoObject.current_w, infoObject.current_h) # 840 x 480
FPSCLOCK = pygame.time.Clock()

path = "/home/imas/shinycalender/"  # Specify the path where the images and videos are stored
current_month =datetime.now().strftime('%m')
files = [f for f in os.listdir(path) if (f.endswith('r.jpg') or f.endswith('1.jpg')) and f[2:4] == current_month]
print(files)
random.shuffle(files)  # Shuffle the files randomly
interval = 180  # Interval to switch images (in seconds)

def get_average_color(image, x_start, x_end, y_start, y_end):
    pixel_array = pygame.surfarray.array3d(image)
    
    selected_pixels = pixel_array[x_start:x_end, y_start:y_end]
    average_color = np.mean(selected_pixels, axis=(0,1))
    return average_color

def is_color_bright(color):
    brightness = 0.299*color[0] + 0.587*color[1] + 0.114*color[2]
    return brightness >200
    

def main():
    pic_num = 0
    last_switch_time = datetime.now()  # Time when the last image switch occurred

    pygame.mouse.set_visible(False)


    while True:
        # Clock information
        now_time = datetime.now()
        font = pygame.font.SysFont("orcb", 50)
        today = now_time.strftime("%m / %d")
        time = now_time.strftime("%H:%M")
        weekday = now_time.strftime('%a')
        
        # check the event
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                elif event.key == K_j:
                    pic_num = (pic_num + 1) % len(files)
                    last_switch_time = datetime.now()
            elif event.type == MOUSEBUTTONDOWN:
                print(files[pic_num])
                # Check if the current image ends with '1.jpg' and switch to '2.jpg', or vice versa
                if files[pic_num].endswith('1.jpg'):
                    # Switch from '1.jpg' to '2.jpg'
                    files[pic_num] = files[pic_num][:-5] + '2.jpg'  # Create the new file name ending with '2.jpg'
                elif files[pic_num].endswith('2.jpg'):
                    # Switch from '2.jpg' to '1.jpg'
                    files[pic_num] = files[pic_num][:-5] + '1.jpg'  # Create the new file name ending with '1.jpg'


        SURFACE.fill((0, 0, 0))

        # Check if the current time is interval seconds past the last switch time
        if (now_time - last_switch_time).seconds >= interval:
            pic_num = (pic_num + 1) % len(files)
            last_switch_time = datetime.now()

        # Load and display the image, scaling it to fit the screen
        try:
            pic_path = os.path.join(path, files[pic_num])
            pic = pygame.image.load(pic_path)
        except:
            print(pic_path)
            pic_num = (pic_num + 1) % len(files)
        pic = pygame.transform.scale(pic, (infoObject.current_w, infoObject.current_h))  # Scale image to screen size
        SURFACE.blit(pic, (0, 0))  # Display the image

        avg_color = get_average_color(pic, 500, 800, 400, 480)
        text_color = (0,0,0) if is_color_bright(avg_color) else (250, 250, 250)
        
        # draw time
        time = font.render(today + " " + time + "(" + weekday + ")", True, text_color)
        SURFACE.blit(time, (500,450))
        
        pygame.display.update()
        FPSCLOCK.tick(1000)  # Set FPS to refresh the screen

if __name__ == '__main__':
    main()

ちょっとこだわったところは、時計の色を背景画像を取得して白と黒の見やすい方に代わるようにしました。

def get_average_color(image, x_start, x_end, y_start, y_end):
    pixel_array = pygame.surfarray.array3d(image)
    
    selected_pixels = pixel_array[x_start:x_end, y_start:y_end]
    average_color = np.mean(selected_pixels, axis=(0,1))
    return average_color

def is_color_bright(color):
    brightness = 0.299*color[0] + 0.587*color[1] + 0.114*color[2]
    return brightness >200

ほんとはフォントをシャニマスお馴染みのハミングにしたかったんだけど導入の仕方がわからなくて断念しました…

季節を感じますね
途中で落として画面割れたの地味にショック

これで卓上カレンダーとしていい感じになりました!!!

あとは動画再生機能も組み込んで、カレンダー機能の他に、ただただ神画像を眺めるスライドショーモードを実装すれば、目標達成!

この記事が気に入ったらサポートをしてみませんか?