Spaces:
Runtime error
Runtime error
File size: 4,009 Bytes
0ca949f |
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 124 125 126 127 128 129 130 131 132 133 134 135 |
import io
import os
import uuid
from PIL import Image
def validate_image(file_object, allowed_extensions=None):
"""
Validate an uploaded image file
Args:
file_object: The uploaded file object (Streamlit's UploadedFile)
allowed_extensions (list, optional): List of allowed file extensions.
Defaults to ['.jpg', '.jpeg', '.png', '.bmp', '.gif'].
Returns:
bool: True if valid, False otherwise
"""
if allowed_extensions is None:
allowed_extensions = [".jpg", ".jpeg", ".png", ".bmp", ".gif"]
# Check if file exists
if file_object is None:
return False
# Get filename
filename = file_object.name
# Check file extension
file_ext = os.path.splitext(filename)[1].lower()
if file_ext not in allowed_extensions:
return False
try:
# Try opening the image to verify it's valid
image = Image.open(file_object)
image.verify()
# Reset file position
file_object.seek(0)
return True
except Exception as e:
print(f"Image validation error: {e}")
return False
def save_uploaded_image(file_object, upload_folder):
"""
Save an uploaded image to disk with a unique filename
Args:
file_object: The uploaded file object (Streamlit's UploadedFile)
upload_folder (str): The folder to save the image to
Returns:
str: The path to the saved image or None if failed
"""
if file_object is None:
return None
try:
# Reset file pointer to beginning
file_object.seek(0)
# Read file content
contents = file_object.read()
# Create a unique filename
file_ext = os.path.splitext(file_object.name)[1].lower()
unique_filename = f"{uuid.uuid4().hex}{file_ext}"
# Make sure the upload folder exists
os.makedirs(upload_folder, exist_ok=True)
# Define the full file path
file_path = os.path.join(upload_folder, unique_filename)
# Save the file
with open(file_path, "wb") as f:
f.write(contents)
# Verify the saved file can be opened
try:
with Image.open(file_path) as test_img:
# Just test that it can be opened
test_img.verify()
except Exception as e:
print(f"Verification of saved image failed: {e}")
# Try an alternative approach to save the file
img = Image.open(io.BytesIO(contents))
img.save(file_path)
return file_path
except Exception as e:
print(f"Error saving file: {e}")
return None
def resize_image(image, max_size=(800, 800)):
"""
Resize an image while maintaining aspect ratio
Args:
image (PIL.Image.Image or str): Image to resize or path to image
max_size (tuple, optional): Maximum width and height. Defaults to (800, 800).
Returns:
PIL.Image.Image: Resized image
"""
# Handle image input - could be a file path or PIL Image
if isinstance(image, str):
try:
# Explicitly use 'RGB' mode to ensure proper color handling
image = Image.open(image).convert("RGB")
except Exception as e:
raise ValueError(f"Could not open image file: {str(e)}")
# Get original dimensions
width, height = image.size
# Check if resize is needed
if width <= max_size[0] and height <= max_size[1]:
return image
# Calculate new dimensions
if width > height:
new_width = max_size[0]
new_height = int(height * (max_size[0] / width))
else:
new_height = max_size[1]
new_width = int(width * (max_size[1] / height))
# Resize and return
return image.resize((new_width, new_height), Image.LANCZOS)
|