Spaces:
Sleeping
Sleeping
import streamlit as st | |
from PIL import Image, ImageOps | |
import io | |
from streamlit_drawable_canvas import st_canvas | |
# Set Streamlit page configuration | |
st.set_page_config(page_title="Image Transformer", page_icon="🖼️", layout="wide") | |
# Sidebar for navigation and options | |
st.sidebar.title("Transformation Options") | |
operation = st.sidebar.radio( | |
"Choose an operation to perform:", | |
("Mirror", "Resize", "Crop", "Rotate", "Black/White", "Pixelate", "Compress") | |
) | |
# Main title for the app | |
st.title("Image Manipulation with Generative AI") | |
st.write("Upload an image and apply transformations based on your selection") | |
# Upload image | |
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "png", "jpeg"]) | |
if uploaded_file is not None: | |
# Load the image | |
image = Image.open(uploaded_file) | |
# Create two columns for displaying images | |
col1, col3 = st.columns([1, 1]) | |
# Create a middle column for the "Apply" button | |
col2 = st.empty() # This will hold the button | |
# Show the original image (smaller size) in the first column | |
with col1: | |
st.image(image, caption="Original Image", use_column_width=False, width=250) | |
# Variables to store slider values or manual inputs | |
new_width = None | |
new_height = None | |
crop_values = None | |
angle = None | |
pixel_size = None | |
quality = None | |
# Display sliders/input fields based on operation, but only apply when the button is pressed | |
if operation == "Resize": | |
st.write("Resize Image:") | |
new_width = st.number_input("Width (in px)", min_value=50, max_value=2000, value=image.width) | |
new_height = st.number_input("Height (in px)", min_value=50, max_value=2000, value=image.height) | |
elif operation == "Crop": | |
st.write("Crop Image:") | |
st.write("Draw a rectangle on the image to crop it.") | |
canvas_result = st_canvas( | |
stroke_width=1, | |
stroke_color="#FF0000", | |
background_image=image, | |
update_streamlit=True, | |
height=image.height, | |
width=image.width, | |
drawing_mode="rect", | |
key="crop_canvas" | |
) | |
if canvas_result.json_data is not None: | |
try: | |
# Get the rectangle from the canvas | |
rect = canvas_result.json_data["objects"][0] | |
left = int(rect["left"]) | |
top = int(rect["top"]) | |
width = int(rect["width"]) | |
height = int(rect["height"]) | |
crop_values = (left, top, left + width, top + height) | |
except IndexError: | |
st.write("No rectangle drawn yet.") | |
elif operation == "Rotate": | |
angle = st.number_input("Rotate Image clockwise (in degrees)", min_value=0, max_value=360, value=0) | |
elif operation == "Pixelate": | |
pixel_size = st.number_input("Pixelate Size (larger number = more pixelation)", min_value=1, max_value=50, value=10) | |
elif operation == "Compress": | |
quality = st.number_input("Image Quality (Compression)", min_value=10, max_value=100, value=80) | |
# Apply button with dynamic label based on the operation | |
apply_button_label = f"Apply {operation}" | |
if col2.button(apply_button_label): | |
# Only generate the output when the "Apply" button is clicked | |
with col3: | |
# Mirror Operation | |
if operation == "Mirror": | |
mirrored_image = ImageOps.mirror(image) | |
st.image(mirrored_image, caption=" ", use_column_width=False, width=250) | |
# Download button for mirrored image | |
buffered = io.BytesIO() | |
mirrored_image.save(buffered, format="PNG") | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="mirrored_image.png", mime="image/png") | |
# Resize Operation | |
elif operation == "Resize" and new_width and new_height: | |
resized_image = image.resize((new_width, new_height), Image.LANCZOS) | |
st.image(resized_image, caption=" ", use_column_width=False, width=250) | |
# Download button for resized image | |
buffered = io.BytesIO() | |
resized_image.save(buffered, format="PNG") | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="resized_image.png", mime="image/png") | |
# Crop Operation | |
elif operation == "Crop" and crop_values: | |
cropped_image = image.crop(crop_values) | |
st.image(cropped_image, caption=" ", use_column_width=False, width=250) | |
# Download button for cropped image | |
buffered = io.BytesIO() | |
cropped_image.save(buffered, format="PNG") | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="cropped_image.png", mime="image/png") | |
# Rotate Operation | |
elif operation == "Rotate" and angle is not None: | |
rotated_image = image.rotate(-angle) # Negative to rotate clockwise | |
st.image(rotated_image, caption=" ", use_column_width=False, width=250) | |
# Download button for rotated image | |
buffered = io.BytesIO() | |
rotated_image.save(buffered, format="PNG") | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="rotated_image.png", mime="image/png") | |
# Black/White Operation | |
elif operation == "Black/White": | |
bw_image = image.convert("L") | |
st.image(bw_image, caption=" ", use_column_width=False, width=250) | |
# Download button for black-and-white image | |
buffered = io.BytesIO() | |
bw_image.save(buffered, format="PNG") | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="bw_image.png", mime="image/png") | |
# Pixelate Operation | |
elif operation == "Pixelate" and pixel_size: | |
small = image.resize((image.width // pixel_size, image.height // pixel_size), Image.NEAREST) | |
pixelated_image = small.resize((image.width, image.height), Image.NEAREST) | |
st.image(pixelated_image, caption=" ", use_column_width=False, width=250) | |
# Download button for pixelated image | |
buffered = io.BytesIO() | |
pixelated_image.save(buffered, format="PNG") | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="pixelated_image.png", mime="image/png") | |
# Compress Operation | |
elif operation == "Compress" and quality: | |
# Save the image with the specified quality | |
buffered = io.BytesIO() | |
image.save(buffered, format="JPEG", quality=quality) | |
st.image(image, caption=" ", use_column_width=False, width=250) | |
# Download button for compressed image | |
st.download_button("Download Image", data=buffered.getvalue(), file_name="compressed_image.jpeg", mime="image/jpeg") | |