RafaelJaime's picture
last push, change description
371bc77
import gradio as gr
from src.utils.change_format import change_format
from src.utils.remove_background import remove_background
from src.utils.generate_image import generate_image
from src.utils.add_text import add_text_to_image_base64
from src.utils.compress import compress_image_memory
from src.utils.generate_image import generate_image
from src.utils.apply_filter import apply_filter_direct
from src.utils.watermark import add_watermark, remove_watermark
from src.utils.describe import describe_image
import base64
from PIL import Image
import io
import requests
from io import BytesIO
from typing import Union
def change_format(image: Union[str, BytesIO], target_format: str) -> str:
"""
Change the format of an image from a URL to the specified target format.
"""
if not isinstance(image, BytesIO):
response = requests.get(image, timeout=30)
response.raise_for_status()
img = Image.open(BytesIO(response.content))
else:
img = Image.open(image)
output = BytesIO()
img.save(output, format=target_format)
output.seek(0)
encoded_image = base64.b64encode(output.getvalue()).decode('utf-8')
return encoded_image
def image_to_base64(image):
if image is None:
return None
buffer = io.BytesIO()
image.save(buffer, format="PNG")
return base64.b64encode(buffer.getvalue()).decode()
def base64_to_image(base64_str):
if not base64_str:
return None
if isinstance(base64_str, str) and "base64," in base64_str:
base64_str = base64_str.split("base64,", 1)[1]
try:
if isinstance(base64_str, str):
base64_str = base64_str.strip()
image_data = base64.b64decode(base64_str)
if not image_data:
print("Decoded base64 data is empty")
return None
image = Image.open(io.BytesIO(image_data))
return image.copy()
except binascii.Error as e:
print(f"Base64 decoding error: {str(e)}")
if isinstance(base64_str, str):
preview = base64_str[:30] + "..." if len(base64_str) > 30 else base64_str
print(f"Base64 preview: {preview}")
return None
except Exception as e:
print(f"Error converting base64 to image: {str(e)}")
if isinstance(base64_str, str):
preview = base64_str[:30] + "..." if len(base64_str) > 30 else base64_str
print(f"Base64 preview: {preview}")
if 'image_data' in locals() and image_data:
try:
magic_bytes = image_data[:12].hex()
print(f"First 12 bytes: {magic_bytes}")
except:
pass
return None
def url_to_base64(url):
response = requests.get(url)
return base64.b64encode(response.content).decode()
def gradio_remove_background(image):
"""
Attempt to remove watermarks from an image using contrast and brightness adjustment.
Args:
image_input: PIL Image object or base64 string
alpha: Contrast control (1.0-3.0, default 2.0). Higher values increase contrast.
beta: Brightness control (-255 to 255, default -160). Negative values decrease brightness.
Returns:
PIL Image object with watermark removal attempted
"""
if image is None:
return None
base64_img = image_to_base64(image)
result = remove_background(f"data:image/png;base64,{base64_img}")
if isinstance(result, str):
return base64_to_image(result)
elif isinstance(result, dict) and "image_data" in result:
if isinstance(result["image_data"], str) and result["image_data"].startswith("data:"):
return base64_to_image(result["image_data"])
else:
try:
return base64_to_image(result["image_data"])
except Exception as e:
print(f"Error processing image data: {e}")
return None
else:
print(f"Unexpected response format from remove_background: {type(result)}")
return None
def gradio_describe_image(image):
if image is None:
return "No image provided"
try:
base64_img = image_to_base64(image)
return describe_image(base64_img)
except Exception as e:
print(f"Error describing image: {e}")
return f"Error: {str(e)}"
def gradio_change_format(image, format_type):
if image is None:
return None
try:
base64_img = image_to_base64(image)
result = change_format(base64_img, format_type)
return base64_to_image(result)
except Exception as e:
print(f"Error changing format: {e}")
return image
def gradio_generate_image(prompt, width=512, height=512):
result = generate_image(prompt, width, height)
return base64_to_image(result["b64"])
def gradio_apply_filter(image, filter_type, intensity=1.0):
if image is None:
print("No image provided")
return None
return apply_filter_direct(image, filter_type, intensity)
def update_text_image(image, text, centered, x, y, font_size, color):
if image is None:
return None
if not text or text.strip() == "":
return image
result = add_text_to_image_base64(image, text, int(x), int(y), int(font_size), color, centered)
return result
def toggle_position_fields(centered):
return (
gr.Number(interactive=not centered),
gr.Number(interactive=not centered)
)
def toggle_intensity_slider(filter_type):
intensity_filters = ['blur', 'brightness', 'contrast', 'saturation']
return gr.Slider(interactive=filter_type in intensity_filters)
def gradio_add_watermark(image, watermark_text, opacity=0.5):
"""
Gradio wrapper for add_watermark function
"""
if image is None:
return None
if not watermark_text or watermark_text.strip() == "":
return image
try:
result = add_watermark(image, watermark_text, opacity)
return result
except Exception as e:
print(f"Error in gradio_add_watermark: {e}")
return image
def gradio_remove_watermark(image):
if image is None:
return None
try:
base64_img = image_to_base64(image)
result = remove_watermark(base64_img)
return base64_to_image(result)
except Exception as e:
print(f"Error removing watermark: {e}")
return image
def gradio_compress_image(image, quality=80):
"""
Compress image for Gradio interface
"""
if image is None:
return None
try:
compressed_image = compress_image_memory(image, quality, "JPEG")
return compressed_image
except Exception as e:
print(f"Error compressing image: {e}")
return image
def create_gradio_interface():
with gr.Blocks(title="ImageUtilitiesMCP", theme=gr.themes.Soft()) as demo:
gr.Markdown("# ๐Ÿ–ผ๏ธ ImageUtilitiesMCP")
gr.Markdown("Some tools for image processing and generation.")
with gr.Tabs():
with gr.Tab("๐ŸŽจ Generate Image"):
with gr.Row():
prompt_input = gr.Textbox(label="Prompt", placeholder="Describe the image you want to generate")
with gr.Column():
width_input = gr.Slider(256, 1024, 512, label="Width")
height_input = gr.Slider(256, 1024, 512, label="Height")
generate_btn = gr.Button("Generate", variant="primary")
generated_output = gr.Image(label="Generated Image")
generate_btn.click(
gradio_generate_image,
[prompt_input, width_input, height_input],
generated_output
)
with gr.Tab("๐Ÿ” Describe Image"):
with gr.Row():
describe_input = gr.Image(label="Upload Image", type="pil")
description_output = gr.Textbox(label="Description", lines=4)
describe_input.change(gradio_describe_image, describe_input, description_output)
with gr.Tab("โœ‚๏ธ Remove Background"):
with gr.Row():
bg_input = gr.Image(label="Upload Image", type="pil")
bg_output = gr.Image(label="Background Removed")
bg_input.change(gradio_remove_background, bg_input, bg_output)
with gr.Tab("๐ŸŽญ Apply Filters"):
with gr.Row():
filter_input = gr.Image(label="Upload Image", type="pil")
with gr.Column():
filter_type = gr.Dropdown(
["blur", "sharpen", "vintage", "black_white", "sepia", "emboss", "edge", "smooth", "brightness", "contrast", "saturation", "grayscale"],
label="Filter Type",
value="blur"
)
intensity_slider = gr.Slider(
minimum=0.1,
maximum=300.0,
value=1.0,
step=0.1,
label="Intensity",
interactive=True
)
filter_output = gr.Image(label="Filtered Image")
filter_type.change(
toggle_intensity_slider,
filter_type,
intensity_slider
)
filter_inputs = [filter_input, filter_type, intensity_slider]
for inp in filter_inputs:
inp.change(gradio_apply_filter, filter_inputs, filter_output)
with gr.Tab("๐Ÿ“ Add Text"):
with gr.Row():
text_input = gr.Image(label="Upload Image", type="pil")
with gr.Column():
text_content = gr.Textbox(
label="Text",
placeholder="Enter text to add",
value=""
)
text_centered = gr.Checkbox(label="Center Text", value=False)
with gr.Row():
text_x = gr.Number(
label="X Position",
value=50,
interactive=True,
minimum=0
)
text_y = gr.Number(
label="Y Position",
value=50,
interactive=True,
minimum=0
)
with gr.Row():
font_size = gr.Slider(
minimum=10,
maximum=100,
value=20,
label="Font Size"
)
text_color = gr.ColorPicker(
label="Color",
value="#FFFFFF"
)
add_text_btn = gr.Button("Add Text", variant="primary")
text_output = gr.Image(label="Image with Text")
text_centered.change(
toggle_position_fields,
text_centered,
[text_x, text_y]
)
inputs = [text_input, text_content, text_centered, text_x, text_y, font_size, text_color]
add_text_btn.click(
update_text_image,
inputs,
text_output
)
for inp in inputs:
inp.change(update_text_image, inputs, text_output)
with gr.Tab("๐Ÿ’ง Watermark"):
with gr.Tabs():
with gr.Tab("Add Watermark"):
with gr.Row():
watermark_input = gr.Image(label="Upload Image", type="pil")
with gr.Column():
watermark_text = gr.Textbox(label="Watermark Text")
watermark_opacity = gr.Slider(0.1, 1.0, 0.5, label="Opacity")
watermark_output = gr.Image(label="Watermarked Image")
inputs = [watermark_input, watermark_text, watermark_opacity]
for inp in inputs:
inp.change(gradio_add_watermark, inputs, watermark_output)
with gr.Tab("Remove Watermark"):
with gr.Row():
unwatermark_input = gr.Image(label="Upload Image", type="pil")
unwatermark_output = gr.Image(label="Watermark Removed")
unwatermark_input.change(gradio_remove_watermark, unwatermark_input, unwatermark_output)
with gr.Tab("๐Ÿ—œ๏ธ Compress"):
with gr.Row():
compress_input = gr.Image(label="Upload Image", type="pil")
with gr.Column():
quality_slider = gr.Slider(0, 100, 80, label="Quality %")
compress_output = gr.Image(label="Compressed Image")
compress_input.change(gradio_compress_image, [compress_input, quality_slider], compress_output)
quality_slider.change(gradio_compress_image, [compress_input, quality_slider], compress_output)
with gr.Tab("๐Ÿ”„ Change Format"):
with gr.Row():
format_input = gr.Image(label="Upload Image", type="pil")
with gr.Column():
format_type = gr.Dropdown(
["PNG", "JPEG", "WEBP", "BMP"],
label="Output Format",
value="PNG"
)
format_output = gr.Image(label="Converted Image")
format_input.change(gradio_change_format, [format_input, format_type], format_output)
format_type.change(gradio_change_format, [format_input, format_type], format_output)
return demo
if __name__ == "__main__":
demo = create_gradio_interface()
demo.launch(
mcp_server=True,
server_name="0.0.0.0",
server_port=7860,
show_error=True
)