chara-animator / app3.py
mook84816's picture
Create app3.py
a50a2a4 verified
import gradio as gr
import torch
from diffusers import DiffusionPipeline
from PIL import Image
import numpy as np
import math, tempfile
from scipy.ndimage import map_coordinates
# --- ZeroGPU用の設定 ---
# APIを使わず、自分のSpace内で直接AIを動かします
pipe = DiffusionPipeline.from_pretrained("Lykon/AnyLoRA", torch_dtype=torch.float16)
pipe.to("cuda")
def generate_static(main_cat, sub_cat):
prompt = f"a cute {sub_cat}, {main_cat} theme, high quality, anime style, white background, solo, center"
try:
# 自分のSpaceのGPUで生成
image = pipe(prompt, num_inference_steps=20).images[0]
return image.convert("RGBA"), "✅ 成功しました!"
except Exception as e:
return None, f"❌ エラー: {str(e)}"
# (アニメーション計算 warp_logic, make_gif は前回と同じものを維持)
def warp_logic(img_arr, t, face_p):
h, w = img_arr.shape[:2]
y, x = np.indices((h, w))
dist = np.sqrt((x/w - 0.5)**2 + (y/h - 0.5)**2)
weight = np.clip(dist * 2, 0, 1) if face_p else 1.0
sx = 10 * math.sin(t * 0.3) * weight
sy = 5 * math.sin(t * 0.4) * (1 - y/h) * weight
map_x, map_y = (x + sx).astype(np.float32), (y + sy).astype(np.float32)
warped = np.zeros_like(img_arr)
for c in range(4):
warped[:,:,c] = map_coordinates(img_arr[:,:,c], [map_y, map_x], order=1)
return Image.fromarray(warped)
def make_gif(static_img, face_p):
if static_img is None: return None, "画像がありません"
img_arr = np.array(static_img.resize((400, 400)))
frames = [warp_logic(img_arr, i, face_p).convert("RGB") for i in range(20)]
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".gif")
frames[0].save(tmp.name, save_all=True, append_images=frames[1:], duration=80, loop=0)
return tmp.name, "✅ X投稿用GIF完成!"
with gr.Blocks() as demo:
gr.Markdown("# 🎨 ZeroGPU版 安定メーカー")
with gr.Row():
with gr.Column():
m_cat = gr.Dropdown(["動物", "食べ物", "ファンタジー"], value="動物", label="1. ジャンル")
s_cat = gr.Dropdown(["柴犬", "三毛猫", "ペンギン"], value="柴犬", label="2. キャラ")
gen_btn = gr.Button("🚀 キャラを生成", variant="primary")
face_p = gr.Checkbox(value=True, label="顔の歪みを抑える")
gif_btn = gr.Button("🐦 X投稿用GIFを作成")
with gr.Column():
static_out = gr.Image(label="SUZURI用 (PNG)", type="pil")
gif_out = gr.Image(label="X投稿用 (GIF)")
status = gr.Textbox(label="状況")
gen_btn.click(generate_static, [m_cat, s_cat], [static_out, status])
gif_btn.click(make_gif, [static_out, face_p], [gif_out, status])
demo.launch()