import streamlit as st from PIL import Image import io def compress_image(input_image, output_format, quality=85): """ Compress an image and return the compressed image. Parameters: - input_image (PIL.Image.Image): The input image. - output_format (str): The format of the output image ('JPEG', 'JPG', 'PNG', or 'WEBP'). - quality (int, optional): The quality of the output image (1-100). Default is 85. Returns: - bytes: The compressed image in bytes. """ img_byte_arr = io.BytesIO() if output_format.upper() in ['JPEG', 'JPG']: input_image.save(img_byte_arr, format='JPEG', quality=quality) elif output_format.upper() == 'PNG': input_image.save(img_byte_arr, format='PNG', compress_level=int((100-quality)/10)) elif output_format.upper() == 'WEBP': input_image.save(img_byte_arr, format='WEBP', quality=quality) img_byte_arr = img_byte_arr.getvalue() return img_byte_arr def main(): st.title("Image Compression App") uploaded_file = st.sidebar.file_uploader("Upload an image", type=["jpg", "jpeg", "png", "webp"]) if uploaded_file is not None: try: # Display the uploaded image image = Image.open(uploaded_file) st.sidebar.image(image, caption="Uploaded Image", use_column_width=True) # Get the size of the uploaded file uploaded_file.seek(0, io.SEEK_END) original_size = uploaded_file.tell() uploaded_file.seek(0, io.SEEK_SET) st.sidebar.write(f"Original size: {original_size / 1024:.2f} KB") # Determine the default format based on the original file original_format = image.format if image and image.format else 'JPEG' if original_format.upper() not in ['JPEG', 'JPG', 'PNG', 'WEBP']: original_format = 'JPEG' output_format = st.sidebar.selectbox("Select output format", ['JPEG', 'JPG', 'PNG', 'WEBP'], index=['JPEG', 'JPG', 'PNG', 'WEBP'].index(original_format.upper())) # Convert image to RGB if it has an alpha channel and the output format is JPEG, JPG, or WEBP if image and image.mode in ("RGBA", "P") and output_format.upper() in ['JPEG', 'JPG', 'WEBP']: image = image.convert("RGB") quality = st.sidebar.slider("Select compression quality", 1, 100, 85) # Display estimated size of compressed image compressed_image_bytes = compress_image(image, output_format, quality) compressed_size = len(compressed_image_bytes) st.sidebar.write(f"Estimated compressed size: {compressed_size / 1024:.2f} KB") if st.button("Compress Image"): st.image(compressed_image_bytes, caption="Compressed Image", use_column_width=True) # Determine file extension for download file_extension = output_format.lower() st.download_button( label=f"Download Compressed Image.{file_extension.upper()}", data=compressed_image_bytes, file_name=f"compressed_image.{file_extension}", mime=f"image/{file_extension}" ) except Exception as e: st.error(f"An error occurred: {e}") if __name__ == "__main__": main()