|
import streamlit as st |
|
import requests |
|
import base64 |
|
from PIL import Image |
|
from io import BytesIO |
|
|
|
|
|
|
|
|
|
st.set_page_config(page_title="λν μ½ν μμ±κΈ°", layout="wide") |
|
API_URL = "https://api-inference.huggingface.co/models/black-forest-labs/FLUX.1-Kontext-dev" |
|
headers = {"Authorization": f"Bearer {st.secrets['HF_TOKEN']}"} |
|
|
|
|
|
|
|
|
|
def query_flux(prompt, image_bytes=None): |
|
inputs = {"prompt": prompt} |
|
if image_bytes: |
|
inputs["image"] = base64.b64encode(image_bytes).decode("utf-8") |
|
|
|
response = requests.post(API_URL, headers=headers, json=inputs) |
|
if response.status_code == 200: |
|
image_data = base64.b64decode(response.json()["image"]) |
|
return Image.open(BytesIO(image_data)) |
|
else: |
|
st.error(f"Error: {response.status_code} - {response.text}") |
|
return None |
|
|
|
|
|
|
|
|
|
st.title("π λν μ½ν μμ±κΈ° (FLUX.1 Kontext)") |
|
st.markdown("κ° μ₯λ©΄μ μ€λͺ
μ μ
λ ₯νλ©΄, μ΄μΌκΈ° νλ¦μ λ§λ μ½νλ₯Ό μλμΌλ‘ μμ±ν©λλ€.") |
|
|
|
with st.expander("λ±μ₯μΈλ¬Ό λ° μ€νμΌ μ 보 (μ ν)"): |
|
character_prompt = st.text_area("λ±μ₯μΈλ¬Ό μ€λͺ
(ex. λΉ¨κ° λ§ν λ₯Ό μ΄ μλ
, νμ λλ λ±)", height=100) |
|
reference_image = st.file_uploader("μ°Έμ‘° μ΄λ―Έμ§ μ
λ‘λ (μ ν)", type=["jpg", "png"]) |
|
|
|
st.markdown("### π λν λ΄μ©μ 5κ° μ₯λ©΄μΌλ‘ λλμ΄ μ
λ ₯νμΈμ") |
|
|
|
scene_prompts = [] |
|
for i in range(5): |
|
text = st.text_area(f"μ₯λ©΄ {i+1} μ€λͺ
", key=f"scene_{i}", height=80) |
|
scene_prompts.append(text) |
|
|
|
if st.button("π¨ μ½ν μμ±νκΈ°"): |
|
if not any(scene_prompts): |
|
st.warning("μ΅μ νλ μ΄μμ μ₯λ©΄ μ€λͺ
μ΄ νμν©λλ€.") |
|
else: |
|
ref_bytes = reference_image.read() if reference_image else None |
|
|
|
with st.spinner("μ΄λ―Έμ§λ₯Ό μμ± μ€μ
λλ€..."): |
|
cols = st.columns(5) |
|
for i, prompt in enumerate(scene_prompts): |
|
if not prompt.strip(): |
|
continue |
|
|
|
full_prompt = f"{character_prompt}. {prompt}" if character_prompt else prompt |
|
img = query_flux(full_prompt, ref_bytes) |
|
if img: |
|
cols[i].image(img, caption=f"μ₯λ©΄ {i+1}") |