File size: 4,734 Bytes
74ea516
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import gradio as gr
from PIL import Image
import numpy as np
import random
from io import BytesIO

# Function to enhance contrast of the image
def enhance_contrast(img):
    return img  # placeholder for actual contrast enhancement logic

# Function to detect dominant colors
def get_dominant_colors(image, n_colors=6):
    image = image.resize((150, 150))  # Resize for faster processing
    result = image.convert('P', palette=Image.ADAPTIVE, colors=n_colors)
    result = result.convert('RGB')
    colors = result.getcolors(150 * 150)
    colors = sorted(colors, reverse=True, key=lambda x: x[0])[:n_colors]
    return [color[1] for color in colors]

# Function to convert RGB to HEX
def rgb_to_hex(color):
    return '#%02x%02x%02x' % color

# Function to generate color harmonies
def generate_harmonies(colors):
    harmonies = {}
    for color in colors:
        r, g, b = color
        comp_color = (255 - r, 255 - g, 255 - b)  # complementary color
        analogous1 = ((r + 30) % 255, (g + 30) % 255, (b + 30) % 255)
        analogous2 = ((r - 30) % 255, (g - 30) % 255, (b - 30) % 255)
        harmonies[rgb_to_hex(color)] = {
            'complementary': rgb_to_hex(comp_color),
            'analogous': (rgb_to_hex(analogous1), rgb_to_hex(analogous2))
        }
    return harmonies

# Function to create a LinkedIn-friendly color palette description with CSS code
def create_palette_description(colors):
    descriptions = [
        "A vibrant palette for branding and marketing.",
        "A calming and trustworthy color scheme for professional use.",
        "Bold and energetic colors, perfect for grabbing attention.",
        "Soft and neutral tones, ideal for elegant branding."
    ]
    chosen_description = random.choice(descriptions)
    
    # Generate the HTML palette
    palette_html = f"<h4>{chosen_description}</h4><div style='display:flex; flex-wrap:wrap;'>"
    css_code = "/* Color Palette CSS */\n"
    for i, color in enumerate(colors):
        hex_color = rgb_to_hex(color)
        palette_html += f"<div style='width: 100px; height: 50px; background-color: {hex_color}; margin: 5px;'></div>"
        palette_html += f"<div style='padding: 15px;'>HEX: {hex_color}</div>"
        # Add the CSS code for each color
        css_code += f".color-{i} {{ background-color: {hex_color}; }}\n"
    
    palette_html += "</div>"
    
    return palette_html, css_code

# Function to generate a downloadable palette image
def generate_palette_image(colors):
    img_width = 500
    img_height = 100
    palette_img = Image.new('RGB', (img_width, img_height))
    
    color_width = img_width // len(colors)
    for i, color in enumerate(colors):
        img = Image.new('RGB', (color_width, img_height), color)
        palette_img.paste(img, (i * color_width, 0))
    
    return palette_img  # Return PIL image directly

# Main function to generate palette and display LinkedIn-friendly results
def generate_palette(image_path):
    img = Image.open(image_path)

    # Enhance the contrast
    img = enhance_contrast(img)

    # Extract dominant colors
    n_colors = 6
    colors = get_dominant_colors(img, n_colors)

    # Convert colors to HEX and create palette description with CSS
    palette_html, css_code = create_palette_description(colors)

    # Generate palette image for download
    palette_img = generate_palette_image(colors)

    return palette_html, palette_img, css_code

# Gradio Interface
def gradio_interface(image_path):
    palette_html, palette_img, css_code = generate_palette(image_path)

    # Convert PIL image to NumPy array (Gradio expects a NumPy array or filepath)
    palette_img_np = np.array(palette_img)

    return palette_html, palette_img_np, css_code

# Create the Gradio interface
with gr.Blocks() as interface:
    with gr.Row():
        with gr.Column():
            image_input = gr.Image(type="filepath", label="Upload Image")  # Image Upload
            submit_btn = gr.Button("Submit", elem_id="submit_btn")
            clear_btn = gr.Button("Clear", elem_id="clear_btn")
        
        with gr.Column():
            palette_output = gr.HTML(label="Generated Color Palette")
            palette_image_output = gr.Image(label="Downloadable Palette Image")
            css_code_output = gr.Code(label="Generated CSS Code")  # Display generated CSS code
    
    submit_btn.click(gradio_interface, inputs=[image_input], outputs=[
        palette_output, palette_image_output, css_code_output])

    # Clear button now resets the image input and clears all outputs
    clear_btn.click(lambda: [None, None, None, None], outputs=[
        image_input, palette_output, palette_image_output, css_code_output])

# Launch the interface
interface.launch(share=True)