Compare commits
2 Commits
v1.4.2-rc.
...
v1.4.2-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
| d416463242 | |||
| 25b8cbd79d |
@@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- HEIC/HEIF image format support for iPhone photo uploads
|
- HEIC/HEIF image format support for iPhone photo uploads
|
||||||
- Automatic HEIC to JPEG conversion (browsers cannot display HEIC)
|
- MPO (Multi-Picture Object) format support for iPhone depth/portrait photos
|
||||||
|
- Automatic HEIC/MPO to JPEG conversion (browsers cannot display these formats)
|
||||||
- Graceful error handling if pillow-heif library not installed
|
- Graceful error handling if pillow-heif library not installed
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|||||||
@@ -160,6 +160,18 @@ def validate_image(file_data: bytes, filename: str) -> Tuple[bytes, str, int, in
|
|||||||
file_data = output.getvalue()
|
file_data = output.getvalue()
|
||||||
img = Image.open(io.BytesIO(file_data))
|
img = Image.open(io.BytesIO(file_data))
|
||||||
|
|
||||||
|
# MPO (Multi-Picture Object) conversion (v1.4.2)
|
||||||
|
# MPO is used by iPhones for depth/portrait photos - extract primary image as JPEG
|
||||||
|
if img.format == 'MPO':
|
||||||
|
output = io.BytesIO()
|
||||||
|
# Convert to RGB if needed
|
||||||
|
if img.mode in ('RGBA', 'P'):
|
||||||
|
img = img.convert('RGB')
|
||||||
|
img.save(output, format='JPEG', quality=95)
|
||||||
|
output.seek(0)
|
||||||
|
file_data = output.getvalue()
|
||||||
|
img = Image.open(io.BytesIO(file_data))
|
||||||
|
|
||||||
# Check format is allowed
|
# Check format is allowed
|
||||||
if img.format:
|
if img.format:
|
||||||
format_lower = img.format.lower()
|
format_lower = img.format.lower()
|
||||||
@@ -170,7 +182,15 @@ def validate_image(file_data: bytes, filename: str) -> Tuple[bytes, str, int, in
|
|||||||
mime_type = 'image/jpeg'
|
mime_type = 'image/jpeg'
|
||||||
|
|
||||||
if mime_type not in ALLOWED_MIME_TYPES:
|
if mime_type not in ALLOWED_MIME_TYPES:
|
||||||
raise ValueError(f"Invalid image format. Accepted: JPEG, PNG, GIF, WebP")
|
# Log the detected format for debugging (v1.4.2)
|
||||||
|
try:
|
||||||
|
current_app.logger.warning(
|
||||||
|
f'Media upload rejected format: filename="{filename}", '
|
||||||
|
f'detected_format="{img.format}", mime_type="{mime_type}"'
|
||||||
|
)
|
||||||
|
except RuntimeError:
|
||||||
|
pass # Outside app context
|
||||||
|
raise ValueError(f"Invalid image format '{img.format}'. Accepted: JPEG, PNG, GIF, WebP")
|
||||||
else:
|
else:
|
||||||
raise ValueError("Could not determine image format")
|
raise ValueError("Could not determine image format")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user