2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カラー電子ペーパーでデジタルフォトフレームを作る

Posted at

Inky Impression - 7.3"

IMG_1444 (大).JPEG

無題の動画 ‐ Clipchampで作成.gif
(1.5倍速)

高精細で綺麗な表示が可能な7.3インチの電子ペーパー「Inky Impression」を購入したので、デジタルフォトフレームを作ってみました。写真より少し彩度が落ちますが、荒いピクセルも相まって味のある画になります。

裏面にはRaspberry Piシリーズをそのまま差せるピンヘッダがついています。

IMG_1445.JPEG

表示するもの

日本の情景写真が掲載されているサイト。CC BY 4.0でライセンスされているので、クレジットを記載すれば自由に利用できます。

GitHubにリポジトリがあり、ここから写真とそれに関するデータを取得できます。
https://github.com/code4fukui/find47

完成したもの

Inky 2.1.0

main.py
main.py
import requests
import random
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
import json
from inky.auto import auto

def resize(img, target_size, background_color=(0, 0, 0)):
    target_w, target_h = target_size
    original_w, original_h = img.size

    # アスペクト比を維持したままリサイズ
    ratio = min(target_w / original_w, target_h / original_h)
    new_w = int(original_w * ratio)
    new_h = int(original_h * ratio)
    resized_img = img.resize((new_w, new_h))

    return resized_img


def main():
    images = None

    # 画像データのjsonを開く
    try:
        with open("/home/pi/impression73/inky/images.json", "r", encoding="utf-8") as f:
            images = json.load(f)
    except Exception as e:
        print("画像データの読み込みに失敗:", e)
        return

    # ランダムに1枚選択
    selected_image = random.choice(images.get("images"))
    title = selected_image.get("title", "No title")
    prefecture = selected_image.get("prefecture", {}).get("name_ja", "No prefecture")
    photographer = selected_image.get("phtotographer", {}).get("name", "Unknown")
    image_url = selected_image.get("url")

    print(title)
    print(prefecture)
    print(photographer)
    print(image_url)

    # ダウンロード
    try:
        image_response = requests.get(image_url)
        image_response.raise_for_status()
        image = Image.open(BytesIO(image_response.content))
    except Exception as e:
        print("画像の取得に失敗:", e)

    #Inkyで表示
    inky = auto(ask_user=True, verbose=True)
    resized_image = resize(image, inky.resolution)

    # 背景キャンバスを作成(黒)
    image = Image.new("RGB", inky.resolution, (0, 0, 0))
    image.paste(resized_image)

    dr = ImageDraw.Draw(image)

    fontFile = "/usr/share/fonts/opentype/note/NotoSansCJKjp-Regular.otf"
    fontSize = 16
    font = ImageFont.truetype(fontFile, fontSize)
    padding = (inky.resolution[1] - resized_image.size[1]) // 4
    dr.text((padding, inky.resolution[1] - padding // 2), title + "" + prefecture + "", anchor="ld", font=font)

    fontFile = "/usr/share/fonts/opentype/note/NotoSansCJKjp-Regular.otf"
    fontSize = 10
    font = ImageFont.truetype(fontFile, fontSize)
    dr.text((inky.resolution[0] - padding, inky.resolution[1]), "Photo by " + photographer + " / CC BY 4.0 / edited\n" + image_url, anchor="rd", spacing=2, font=font)

    inky.set_image(image)
    inky.show()

if __name__ == "__main__":
    main()

写真を表示する

写真の情報の取得

最初に電子ペーパーのセットアップをしておきます。
https://learn.pimoroni.com/article/getting-started-with-inky-impression

先ほどのリポジトリにimages.jsonというファイルがあります。中身はこんな感じ↓

images.json
{
    "images": [
        {
            "id": 1132,
            "code": "gy7lt",
            "url": "https://find47.jp/ja/i/gy7lt/image_file",
            "thumb_url": "https://find47.jp/ja/i/gy7lt/image_file?type=thumb",
            "page_url": "https://find47.jp/ja/i/gy7lt",
            "title": "生後1ヶ月の子鹿",
            "prefecture": {
                "code": 1,
                "dn": "hokkaido",
                "name_ja": "北海道",
                "name_en": "Hokkaido"
            },
            "phtotographer": {
                "name": "kkawamura"
            },
            "award": ""
        },

全ての写真のデータが入っているので、これをダウンロードしておきます。

cd ~/Downloads/
wget -O images.json https://raw.githubusercontent.com/code4fukui/find47/main/images.json

随時更新されているようなので、スクリプトを組んで定期的にダウンロードするようにしてもいいかもしれません。

images.jsonを開く

images = None
try:
    with open("/home/pi/Scripts/impression73/inky/images.json", "r", encoding="utf-8") as f:
        images = json.load(f)
except Exception as e:
    print("画像データの読み込みに失敗:", e)
    return

パスは環境に合わせて修正してください。

ランダムに1枚を選択する

selected_image = random.choice(images.get("images"))

title = selected_image.get("title", "No title")
prefecture = selected_image.get("prefecture", {}).get("name_ja", "No prefecture")
photographer = selected_image.get("phtotographer", {}).get("name", "Unknown")
image_url = selected_image.get("url")

random.choiceで画像を選び、データを取り出します。

写真をダウンロード

try:
    image_response = requests.get(image_url)
    image_response.raise_for_status()
    image = Image.open(BytesIO(image_response.content))
except Exception as e:
    print("画像の取得に失敗:", e)

urlから写真をダウンロードします。

写真をリサイズ

inky = auto(ask_user=True, verbose=True)
resized_image = resize_and_pad(image, inky.resolution)

inkyの初期化で解像度が取得できるので、それに合わせてリサイズします。

写真のアスペクト比は16:9ですが、電子ペーパーは5:3なのでピッタリとはいきません。
そこで余ったスペースにタイトルと県名、ライセンスを表記するようにしました。

表示

inky.set_image(image)
inky.show()

これで表示されます。

定期的に写真を変える

cronで定期的にスクリプトを実行することで、表示する写真を変更します。

こちらを参考に、6時間で1回実行するようにしました。
inkyのライブラリを利用するため、pimoroniの仮想環境のパスを指定します。

0 */6 * * * /home/pi/.virtualenvs/pimoroni/bin/python /home/pi/impression73/inky/main.py

まとめ

カレンダーとかタスクの表示、ガジェット的な運用ができそうで楽しいです。用途にもよりますがRaspberry Pi Zero系の方がかさばらなくてよさそうです。色々遊びつつ、3Dプリンターで筐体を作って飾ろうと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?