【推し活×AI】好きなキャラ風に褒めてくれるミニアプリを自作する方法
画像を1枚アップすると、“好きなキャラ風の口調”で褒め言葉を自動生成し、吹き出し付き画像として返してくれるミニアプリを作ります。 PythonとChatGPT API、そしてStreamlitを使えば、初心者でも短時間で完成。推し活×AIで、毎日がちょっと楽しくなります。
1. 推し活とAIの相性が抜群な理由
1-1. 推し活の魅力を最大化
自分だけの“推しからのひと言”が手元に届く体験は、モチベーションを高める強いトリガーになります。
1-2. AIで生まれる新しいファン体験
ChatGPTの表現力を使えば、そのキャラらしい雰囲気のセリフを安全な範囲で生成できます(固有フレーズは避ける)。
2. 作るアプリのイメージと機能
2-1. 完成イメージ
推しの写真やグッズの画像をアップ → “◯◯主人公っぽく”などの指示 → 褒め言葉を吹き出しに合成してPNGでダウンロード。
2-2. 必要な機能
- 画像アップロード(PNG/JPG)
- 「◯◯風」テキスト入力+宛先名入力
- ChatGPTで褒め言葉を生成(短文)
- 吹き出し+テキストの画像合成
- PNG保存(ダウンロード)
3. 準備するもの
- Python 3.10 以上(推奨)
- OpenAI APIキー(
.env
で安全に保存) - ライブラリ:
streamlit
,Pillow
,python-dotenv
,openai
# セットアップ(ターミナル)
pip install streamlit pillow python-dotenv openai
# .env(プロジェクト直下)
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
4. アプリ制作手順(コード付き)
4-1. プロジェクトの構成
oshi-app/
├─ app.py
└─ .env
4-2. 基本UI(Streamlit)を作る
# app.py(1/3) - UIの基本
import os, io, textwrap
from dotenv import load_dotenv
from PIL import Image, ImageDraw, ImageFont
import streamlit as st
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
st.set_page_config(page_title="推しが褒めてくれるアプリ", page_icon="✨")
st.title("✨ 推しが“褒め言葉”を言ってくれる(吹き出し合成)")
uploaded = st.file_uploader("画像を1枚アップロード(PNG/JPG)", type=["png","jpg","jpeg"])
persona = st.text_input("キャラ/アイドル名(◯◯風・△△っぽく)", value="元気な主人公風")
to_name = st.text_input("宛先(あなた/友達の名前)", value="あなた")
lang = st.selectbox("言語", ["日本語", "English"], index=0)
generate_btn = st.button("褒め言葉を生成して合成する")
4-3. プロンプト設計(“◯◯風”の安全な寄せ方)
“雰囲気にやさしく寄せる”ことを明記し、固有フレーズや名台詞の使用は禁止します。
# app.py(2/3) - プロンプトと生成
def build_prompt(persona: str, to_name: str, lang: str = "日本語") -> str:
return f"""
あなたは「{persona}」の雰囲気にやさしく寄せるコピーライターです。
短い褒め言葉を{lang}で1つだけ出力してください。
条件:
- 宛先: {to_name}
- 30〜60文字程度
- 前向き・具体的・行動を後押し
- 著名人/作品の固有フレーズ・名台詞は使わない
- 差別/中傷/医療・金融の断定助言は不可
出力はテキストのみ。余計な説明や記号は不要。
""".strip()
def gen_phrase(persona: str, to_name: str, lang: str) -> str:
prompt = build_prompt(persona, to_name, lang)
resp = client.chat.completions.create(
model="gpt-5", # プランに合わせてモデル名を調整
messages=[{"role":"user","content": prompt}],
temperature=0.6,
max_tokens=80
)
return resp.choices[0].message.content.strip()
4-4. 吹き出し合成(Pillow)
右上に半透明の吹き出しを描いて、折り返しテキストを載せます。日本語フォントが無い環境ではデフォルトにフォールバック。
# app.py(3/3) - 画像合成とメイン処理
def draw_speech_bubble(base_img: Image.Image, text: str) -> Image.Image:
img = base_img.convert("RGBA")
W, H = img.size
bubble_w, bubble_h = int(W * 0.70), int(H * 0.35)
margin = int(min(W,H) * 0.03)
x0, y0 = W - bubble_w - margin, margin
x1, y1 = x0 + bubble_w, y0 + bubble_h
overlay = Image.new("RGBA", img.size, (0,0,0,0))
d = ImageDraw.Draw(overlay)
radius = int(min(bubble_w, bubble_h) * 0.07)
d.rounded_rectangle([x0,y0,x1,y1], radius=radius, fill=(255,255,255,230), outline=(0,0,0,100), width=2)
tail = [(x1 - int(radius*1.2), y1 - int(radius*0.5)),
(x1 - int(radius*0.3), y1 + int(radius*0.6)),
(x1 - int(radius*2.2), y1 - int(radius*0.2))]
d.polygon(tail, fill=(255,255,255,230), outline=(0,0,0,100))
try:
font = ImageFont.truetype("NotoSansJP-Regular.otf", size=int(bubble_h*0.13))
except:
font = ImageFont.load_default()
wrapped = textwrap.fill(text, width=16)
tw, th = d.multiline_textsize(wrapped, font=font, spacing=6)
tx, ty = x0 + (bubble_w - tw)//2, y0 + (bubble_h - th)//2
d.multiline_text((tx,ty), wrapped, font=font, fill=(20,20,20,255), spacing=6, align="left")
return Image.alpha_composite(img, overlay)
# メイン
if generate_btn:
if not uploaded:
st.error("画像を1枚アップしてください。")
else:
try:
base = Image.open(uploaded).convert("RGB")
phrase = gen_phrase(persona, to_name, lang)
result = draw_speech_bubble(base, phrase)
st.image(result, caption="完成イメージ", use_column_width=True)
buf = io.BytesIO()
result.save(buf, format="PNG")
st.download_button("画像をダウンロード(PNG)", data=buf.getvalue(),
file_name="oshi_phrase.png", mime="image/png")
st.success("生成が完了しました!")
except Exception as e:
st.error(f"処理に失敗しました: {e}")
5. 実際に動かしてみる
5-1. 起動方法(ローカル)
# ターミナルでプロジェクト直下へ
streamlit run app.py
# ブラウザが開く → 画像アップ → 「◯◯風」を入力 → 生成 → PNG保存
5-2. うまくいかない時
- APIキー未設定:
.env
の値や環境変数を再確認 - 文字化け:UTF-8、フォント(Noto系)導入で改善
- レート制限:時間をおいて再試行、出力量(max_tokens)を抑える
6. 公開・共有の方法
6-1. Streamlit Community Cloudで無料公開
- GitHubに
app.py
とrequirements.txt
をpush - StreamlitにGitHub連携してDeploy
- Secretsに
OPENAI_API_KEY
を登録
6-2. SNS共有のコツ
- 完成画像を正方形(1080×1080)に近づけると映える
- ハッシュタグ例:#推し活 #AI #ChatGPT #Python #自作アプリ
7. 著作権・利用規約の注意点
- 個人利用を前提に。商用・配布は各権利者のガイドラインを必ず確認
- 実在人物・キャラの固有フレーズやロゴの使用は避ける
- 誹謗中傷・差別・成人向けなど不適切な生成を避ける
本文のプロンプトでは「雰囲気に寄せるが固有フレーズは使わない」ことを明記し、安全に配慮しています。
8. まとめ
- 画像1枚&数行のコードで、“推しからの励まし”体験を自作できる
- StreamlitでUI化すれば、友だちにも簡単に体験してもらえる
- 次は「毎朝の自動生成」「SNS自動投稿」「多言語対応」などへ拡張
推し活×AIの第一歩として、今日から動かしてみましょう。ちょっとしたひと言が、毎日を少し前向きにしてくれます。