File size: 4,937 Bytes
6c1e018
f7d4fba
6c1e018
1a55b9b
b3ad321
6c1e018
bf8eb41
84a0db0
b3ad321
e408648
10c2f3d
 
 
bf8eb41
10c2f3d
 
 
 
 
 
 
 
 
 
 
 
bf8eb41
 
 
 
 
 
 
 
10c2f3d
 
 
 
 
 
 
 
bf8eb41
10c2f3d
 
 
 
 
 
bf8eb41
10c2f3d
 
01a1d5c
 
 
 
10c2f3d
 
 
 
d860b1d
 
 
 
901181b
d860b1d
 
 
 
 
 
 
bf8eb41
 
 
 
 
aaf0b46
d860b1d
79f0009
01a1d5c
 
 
 
 
 
 
 
afaf3da
bf8eb41
01a1d5c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d396459
d860b1d
b3ad321
bf8eb41
01a1d5c
7060283
e408648
6c1e018
e408648
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
import gradio as gr
from PIL import Image, ImageFilter
import rembg
import io
import base64

def process_image(image, outline_size, outline_color):
    if image is None:
        return None

    try:
        # Convert image to bytes for rembg
        img_byte_arr = io.BytesIO()
        image.save(img_byte_arr, format="PNG", dpi=(300, 300))  # Set DPI here
        img_byte_arr.seek(0)

        # Remove background
        processed_bytes = rembg.remove(img_byte_arr.getvalue())
        processed_img = Image.open(io.BytesIO(processed_bytes)).convert("RGBA")

        # Create outline mask
        alpha = processed_img.split()[-1]
        alpha = Image.merge('L', [alpha])
        blurred = alpha.filter(ImageFilter.GaussianBlur(radius=outline_size))
        new_alpha = blurred.point(lambda x: 0 if x == 0 else 255)  # Binary mask

        # Define outline color based on selection
        if outline_color == "white":
            outline_rgb = (255, 255, 255, 255)  # White
        elif outline_color == "black":
            outline_rgb = (0, 0, 0, 255)  # Black
        else:
            outline_rgb = (255, 255, 255, 255) #Default white

        # Apply outline to the transparent image
        outlined_img = Image.new("RGBA", processed_img.size, (0, 0, 0, 0))  # Fully transparent
        pixels = outlined_img.load()

        alpha_pixels = new_alpha.load()
        for x in range(outlined_img.width):
            for y in range(outlined_img.height):
                if alpha_pixels[x, y] > 0:
                    pixels[x, y] = outline_rgb

        # Overlay original image
        outlined_img = Image.alpha_composite(outlined_img, processed_img)

        # Save the result as bytes for Gradio
        output_buffer = io.BytesIO()
        outlined_img.save(output_buffer, format="PNG", dpi=(300, 300))  # Set DPI here
        output_buffer.seek(0)

        img_data = base64.b64encode(output_buffer.read()).decode("utf-8")
        data_url = f"data:image/png;base64,{img_data}"

        return data_url # Return data_url for display

    except Exception as e:
        print(f"Error processing image: {e}")  # Log the error
        return None

# Gradio Interface
with gr.Blocks(title="Sticker Maker") as interface:
    gr.Markdown("# Sticker Maker")
    gr.Markdown("Upload an image to remove the background and add an outline.")

    with gr.Row():
        with gr.Column():
            image_upload = gr.Image(label="Upload Image", type="pil")
            outline_size = gr.Slider(
                label="Outline Thickness", minimum=0, maximum=20, value=5, step=1
            )
            outline_color = gr.Radio(
                choices=["white", "black"],
                value="white",
                label="Outline Color",
            )
            create_btn = gr.Button("Create Sticker", variant="primary")

        with gr.Column():
          image_output_html = gr.HTML(
                """
                <div style="position: relative;">
                    <img id="sticker-preview" src="" style="max-width: 100%; max-height: 400px;">
                    <a id="download-link" style="position: absolute; top: 10px; right: 10px; background-color: rgba(255, 255, 255, 0.7); padding: 5px; border-radius: 5px; display:none;" download="sticker.png">Download</a>
                </div>
                """
            )

    def update_image(image, outline_size, outline_color):
        try:
            data_url = process_image(image, outline_size, outline_color)
            if data_url:
                return f"""
                    <div style="position: relative;">
                        <img id="sticker-preview" src="{data_url}" style="max-width: 100%; max-height: 400px;">
                        <a id="download-link" href="{data_url}" download="sticker.png" style="position: absolute; top: 10px; right: 10px; background-color: rgba(255, 255, 255, 0.7); padding: 5px; border-radius: 5px;">Download</a>
                    </div>
                    """
            else:
                return """
                    <div style="position: relative;">
                        <img id="sticker-preview" src="" style="max-width: 100%; max-height: 400px;">
                        <a id="download-link" style="position: absolute; top: 10px; right: 10px; background-color: rgba(255, 255, 255, 0.7); padding: 5px; border-radius: 5px; display:none;" download="sticker.png">Download</a>
                    </div>
                    """
        except Exception as e:
            print(f"Error in update_image: {e}")  # Log the error
            return f"""
                    <div style="position: relative;">
                        Error: {e}
                    </div>
                    """

    create_btn.click(
        fn=update_image,
        inputs=[image_upload, outline_size, outline_color],
        outputs=image_output_html,
    )

if __name__ == "__main__":
    interface.launch(debug=True)