File size: 4,250 Bytes
151b1e3
 
1b7c1e0
151b1e3
1b7c1e0
cb4e46f
 
 
c0c995d
151b1e3
 
 
c0c995d
 
151b1e3
c0c995d
 
 
 
 
 
 
 
 
 
151b1e3
 
 
 
 
 
 
 
c0c995d
151b1e3
 
cb4e46f
 
151b1e3
1b7c1e0
151b1e3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cb4e46f
151b1e3
 
 
 
 
 
 
 
 
 
 
cb4e46f
151b1e3
 
 
 
 
 
 
 
 
 
 
 
cb4e46f
151b1e3
 
cb4e46f
 
151b1e3
 
 
 
 
 
 
 
 
 
 
 
 
c0c995d
fe1e3d0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from PIL import Image
from io import BytesIO
import base64
import os
import re
from groq import Groq
import gradio as gr

# Read key from Hugging Face secrets or default fallback
api_key = os.getenv("GROQ_API_KEY", "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")
client = Groq(api_key=api_key)

def encode_image(image_input):
    """Encode image (path, dict, or base64 data URI) to base64 string."""
    try:
        # If Gradio passes a FileData dictionary
        if isinstance(image_input, dict):
            image_input = image_input.get("path", "")

        # If already a base64 Data URI string
        if isinstance(image_input, str) and image_input.startswith("data:image"):
            return image_input.split(",")[1]

        # Otherwise treat as a local file path and open via PIL
        image = Image.open(image_input).convert("RGB")

        base_height = 512
        h_percent = (base_height / float(image.size[1]))
        w_size = int((float(image.size[0]) * float(h_percent)))
        image = image.resize((w_size, base_height), Image.LANCZOS)

        buffered = BytesIO()
        image.save(buffered, format="JPEG")
        return base64.b64encode(buffered.getvalue()).decode("utf-8")
    except Exception as e:
        print(f"Error encoding image: {e}")
        return None

def feifeichat(image):
    try:
        if image is None:
            return "Please upload a photo"

        base64_image = encode_image(image)
        if not base64_image:
            return "Error processing image"

        messages = [
            {
                "role": "user",
                "content": [
                    {
                        "type": "text", 
                        "text": "Analyze the image and return strictly valid JSON format with keys 'title', 'description', 'meta_title' (max 60 chars), 'meta_description' (max 155 chars), 'tags' (array of 5-8 strings), 'style_breakdown' (object with keys: aesthetic, top, bottom, legwear, accessories), and 'faqs' (array of two objects with 'q' and 'a'). Follow these strict copywriting guidelines: 1. Description must be an elegant, descriptive paragraph (3-4 sentences) written like an alternative fashion lookbook. 2. Focus on physical aesthetics: mention terms like 'slender body', 'petite frame', 'youthful appeal', 'cute vibe', and 'sexy style' naturally. 3. Avoid literal camera actions: DO NOT say 'taking a selfie', 'mirror picture', or 'holding a phone'. Describe the pose as casual, relaxed, or playful. 4. Tags must be individual aesthetic search terms (e.g., ['egirl-aesthetic', 'thigh-highs', 'white-tights', 'alternative-fashion'])."
                    },
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": f"data:image/jpeg;base64,{base64_image}"
                        }
                    }
                ]
            }
        ]

        response = client.chat.completions.create(
            model="qwen/qwen3.6-27b",
            messages=messages,
            response_format={"type": "json_object"},
            temperature=0.7,
            stream=False
        )

        raw_content = response.choices[0].message.content or ""

        # Strip Qwen reasoning/thinking blocks (<think>...</think>)
        cleaned = re.sub(r'<think>.*?</think>', '', raw_content, flags=re.DOTALL).strip()

        # Strip markdown fences if present
        cleaned = re.sub(r'^```(?:json)?\s*', '', cleaned)
        cleaned = re.sub(r'\s*```$', '', cleaned)

        return cleaned.strip()

    except Exception as e:
        print(f"Error: {e}")
        return f"An error occurred while processing your request: {e}"

with gr.Blocks() as demo:
    gr.Markdown("Image To Flux Prompt")
    with gr.Tab(label="Image To Flux Prompt"):
        input_img = gr.Image(label="Input Picture", height=320, type="filepath")
        output_text = gr.Textbox(label="Flux Prompt")
        submit_btn = gr.Button(value="Submit")

    submit_btn.click(
        fn=feifeichat,
        inputs=input_img,
        outputs=output_text,
        api_name="feifeichat"
    )

# Disabling SSR mode resolves SvelteKit 405 Method Not Allowed errors on Gradio 5
demo.launch(ssr_mode=False)