8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1. はじめに

ある日Twitterを眺めていると、思わず目を引くツイートが流れてきました。

なんと、iOSアプリ開発者のharuさんがサンタになっていました!
羨ましい、、、私もサンタになりたい!!

この瞬間『人類サンタ化計画🎅🤶』が始動しました。

2. 実装

2.1. 仕様

このアプリは、とても簡単にサンタクロースの帽子を追加したプロフィール画像を作成することで、人類のサンタ化を促進するものです。

主な仕様は以下の通りです:

  • 画像アップロード機能: ユーザーが任意の画像をアップロード可能。
  • 帽子のカスタマイズ: 帽子のサイズ、位置、回転をスライダーで自由に調整可能。
  • 画像保存・ダウンロード: 生成した画像をローカルに保存してダウンロード可能。

簡単な操作で誰でもサンタに変身できます!

2.2. ディレクトリ構成

以下はプロジェクトのディレクトリ構成です:

santa-claus-hats/
├── app.py                 # Streamlitアプリのメインスクリプト
├── requirements.txt       # 必要なパッケージ一覧
├── assets/                # 静的ファイルを格納
│   └── santa_hat.png      # サンタクロースの帽子画像
├── outputs/               # ユーザーが生成した画像の保存先
└── utils/                 # ユーティリティ関数やヘルパースクリプトを格納

ソースコードは下記のGitHubレポジトリからご確認ください:

2.3. ソースコード

主なポイント

以下はアプリ実装の主要なポイントです:

  1. StreamlitによるシンプルなUI設計: プロフィール画像のアップロードから帽子の調整、生成画像のプレビューまでを一貫して提供。
  2. Pillowを使った画像処理: 帽子の位置、サイズ、回転をリアルタイムで調整可能。
  3. ダウンロード機能: 生成画像を即座にダウンロードできる手軽さ。

app.py

import os

import streamlit as st
from PIL import Image

# サンタクロースの帽子画像のパス
SANTA_HAT_PATH = "assets/santa_hat.png"
OUTPUT_DIR = "outputs"


# ディレクトリの準備
def prepare_directories():
    os.makedirs(OUTPUT_DIR, exist_ok=True)


# サンタクロースの帽子をプロフィール画像に合成する関数
def add_santa_hat(
    profile_image: Image.Image,
    santa_hat: Image.Image,
    hat_scale: float,
    hat_offset_x: int,
    hat_offset_y: int,
    hat_rotation: int,
) -> Image.Image:
    """
    プロフィール画像にサンタクロースの帽子を重ねる。

    Parameters:
        profile_image (Image.Image): ユーザーがアップロードしたプロフィール画像。
        santa_hat (Image.Image): サンタクロースの帽子画像。
        hat_scale (float): 帽子のサイズを調整するスケール。
        hat_offset_x (int): 帽子の横方向のオフセット。
        hat_offset_y (int): 帽子の縦方向のオフセット。
        hat_rotation (int): 帽子の回転角度。

    Returns:
        Image.Image: 合成された画像。
    """
    profile_image = profile_image.convert("RGBA")
    santa_hat = santa_hat.convert("RGBA")

    # 帽子のサイズをプロフィール画像に合わせて調整
    hat_width = int(profile_image.width * hat_scale)
    hat_height = int(santa_hat.height * (hat_width / santa_hat.width))
    santa_hat = santa_hat.resize((hat_width, hat_height), Image.Resampling.LANCZOS)

    # 帽子を回転
    santa_hat = santa_hat.rotate(hat_rotation, expand=True)

    # 帽子の位置(中央に配置し、オフセットを適用)
    hat_position = (
        (profile_image.width - santa_hat.width) // 2
        + hat_offset_x,  # 中央揃え + 横方向オフセット
        hat_offset_y,  # 縦方向のオフセット
    )

    # 画像を合成
    combined_image = Image.alpha_composite(
        profile_image, Image.new("RGBA", profile_image.size, (0, 0, 0, 0))
    )
    combined_image.paste(santa_hat, hat_position, santa_hat)

    return combined_image


# Streamlitアプリ
def main():
    st.title("サンタプロフィール画像メーカー")

    # サンタ帽子のロード
    try:
        santa_hat = Image.open(SANTA_HAT_PATH)
    except FileNotFoundError:
        st.error(
            "サンタクロースの帽子画像が見つかりません!assetsディレクトリにsanta_hat.pngを配置してください。"
        )
        return

    # プロフィール画像のアップロード
    uploaded_file = st.file_uploader(
        "プロフィール画像をアップロードしてください", type=["jpg", "jpeg", "png"]
    )

    if uploaded_file is not None:
        profile_image = Image.open(uploaded_file)

        # 帽子のサイズ、位置、回転を調整するスライダー
        hat_scale = st.slider(
            "帽子のサイズ (画像幅に対する割合)",
            min_value=0.1,
            max_value=1.0,
            value=0.6,
            step=0.05,
        )
        hat_offset_x = st.slider(
            "帽子の横方向位置調整",
            min_value=-profile_image.width,
            max_value=profile_image.width,
            value=0,
            step=5,
        )
        hat_offset_y = st.slider(
            "帽子の縦方向位置調整",
            min_value=-profile_image.height,
            max_value=profile_image.height,
            value=-10,
            step=5,
        )
        hat_rotation = st.slider(
            "帽子の回転角度 (度)", min_value=-180, max_value=180, value=0, step=5
        )

        # サンタクロースの帽子を合成
        combined_image = add_santa_hat(
            profile_image,
            santa_hat,
            hat_scale,
            hat_offset_x,
            hat_offset_y,
            hat_rotation,
        )

        # 合成画像を表示
        st.image(
            combined_image,
            caption="サンタクロースプロフィール画像",
            use_container_width=True,
        )

        # 画像をダウンロード可能にする
        output_path = os.path.join(OUTPUT_DIR, "santa_profile.png")
        combined_image.save(output_path, format="PNG")

        with open(output_path, "rb") as file:
            st.download_button(
                label="画像をダウンロード",
                data=file,
                file_name="santa_profile.png",
                mime="image/png",
            )


if __name__ == "__main__":
    prepare_directories()
    main()

3. セキュリティについて補足

本アプリでは、以下のような点に配慮しています:

  1. データの削除: アップロードされたデータはアプリのリロード時に削除されます。

  2. データの非公開性: アップロードされたデータが他のユーザーに閲覧されることはありません。

  3. 秘匿性の高い画像のアップロードは非推奨: 傍受の可能性を完全に排除することはできないため、秘匿性の高い画像のアップロードはお控えください。

これらの点を踏まえ、適切にアプリをご利用ください。

4. アプリの使い方

アプリの使い方はとても簡単です。

  1. 画像をアップロードする: 任意のプロフィール画像をアップロードします。

  2. 帽子をカスタマイズする: スライダーを操作して、帽子のサイズ、位置、回転を調整します。

  3. 画像をダウンロードする: アプリ下部の“画像をダウンロード”ボタンを押して、生成画像を保存します。

image.png

5. アプリのリンク

以下のリンクからアプリをお試しください。皆さんも一緒にサンタになりましょう!🎅🤶

8
3
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
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?