| from PIL import Image |
| from io import BytesIO |
| import base64 |
| import os |
| import re |
| from groq import Groq |
| import gradio as gr |
|
|
| |
| 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 isinstance(image_input, dict): |
| image_input = image_input.get("path", "") |
|
|
| |
| if isinstance(image_input, str) and image_input.startswith("data:image"): |
| return image_input.split(",")[1] |
|
|
| |
| 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 "" |
|
|
| |
| cleaned = re.sub(r'<think>.*?</think>', '', raw_content, flags=re.DOTALL).strip() |
|
|
| |
| 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" |
| ) |
|
|
| |
| demo.launch(ssr_mode=False) |