import streamlit as st from PIL import Image import numpy as np import io import zipfile # Title of the app st.title("Image Transformation App") # Upload image files uploaded_files = st.file_uploader("Upload Images", type=["jpg", "jpeg", "png"], accept_multiple_files=True) if uploaded_files: images = [Image.open(file) for file in uploaded_files] st.header("Uploaded Images") for i, image in enumerate(images): st.image(image, caption=f"Image {i+1}", use_container_width=True) # Transformation options st.header("Select Transformations") options = st.multiselect("Choose transformations:", [ "Rotation", "Scaling", "Shearing", "Cropping", ]) # Parameters for transformations angle = scale_factor = shear_factor = left = top = right = bottom = None if "Rotation" in options: angle = st.slider("Rotation Angle (degrees):", 0, 360, 90) if "Scaling" in options: scale_factor = st.slider("Scaling Factor:", 0.1, 3.0, 1.0) if "Shearing" in options: shear_factor = st.slider("Shearing Factor:", -0.5, 0.5, 0.0) if "Cropping" in options: left = st.slider("Left Crop:", 0, min([image.width for image in images]) - 1, 0) top = st.slider("Top Crop:", 0, min([image.height for image in images]) - 1, 0) right = st.slider("Right Crop:", left + 1, min([image.width for image in images]), min([image.width for image in images])) bottom = st.slider("Bottom Crop:", top + 1, min([image.height for image in images]), min([image.height for image in images])) # Perform transformations transformed_images = [] for image in images: transformed_image = image.copy() if "Rotation" in options and angle is not None: transformed_image = transformed_image.rotate(angle) if "Scaling" in options and scale_factor is not None: new_size = (int(transformed_image.width * scale_factor), int(transformed_image.height * scale_factor)) transformed_image = transformed_image.resize(new_size) if "Shearing" in options and shear_factor is not None: matrix = [ 1, shear_factor, 0, 0, 1, 0 ] transformed_image = transformed_image.transform(transformed_image.size, Image.AFFINE, matrix) if "Cropping" in options and left is not None and top is not None and right is not None and bottom is not None: transformed_image = transformed_image.crop((left, top, right, bottom)) transformed_images.append(transformed_image) # Display transformed images st.header("Transformed Images") for i, transformed_image in enumerate(transformed_images): st.image(transformed_image, caption=f"Transformed Image {i+1}", use_column_width=True) # Download all transformed images as a zip file if transformed_images: zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, "w") as zf: for i, transformed_image in enumerate(transformed_images): img_buffer = io.BytesIO() transformed_image.save(img_buffer, format="PNG") zf.writestr(f"transformed_image_{i+1}.png", img_buffer.getvalue()) zip_buffer.seek(0) st.download_button( label="Download All Transformed Images", data=zip_buffer, file_name="Transformed_images.zip", mime="application/zip", )