svg image support #374

This commit is contained in:
rimu 2024-12-06 10:21:44 +13:00
parent 4f95d1237e
commit 4e87a365b3
7 changed files with 43 additions and 30 deletions

View file

@ -155,7 +155,7 @@ class CreateImageForm(CreatePostForm):
def validate(self, extra_validators=None) -> bool:
uploaded_file = request.files['image_file']
if uploaded_file and uploaded_file.filename != '':
if uploaded_file and uploaded_file.filename != '' and not uploaded_file.filename.endswith('.svg'):
Image.MAX_IMAGE_PIXELS = 89478485
# Do not allow fascist meme content
try:

View file

@ -679,13 +679,14 @@ def add_post(actor, type):
Image.MAX_IMAGE_PIXELS = 89478485
# resize if necessary
img = Image.open(final_place)
if '.' + img.format.lower() in allowed_extensions:
img = ImageOps.exif_transpose(img)
if not final_place.endswith('.svg'):
img = Image.open(final_place)
if '.' + img.format.lower() in allowed_extensions:
img = ImageOps.exif_transpose(img)
# limit full sized version to 2000px
img.thumbnail((2000, 2000))
img.save(final_place)
# limit full sized version to 2000px
img.thumbnail((2000, 2000))
img.save(final_place)
request_json['object']['attachment'] = [{'type': 'Image', 'url': f'https://{current_app.config["SERVER_NAME"]}/{final_place.replace("app/", "")}',
'name': form.image_alt_text.data}]

View file

@ -25,7 +25,7 @@ from sqlalchemy import func, desc, text
import os
allowed_extensions = ['.gif', '.jpg', '.jpeg', '.png', '.webp', '.heic', '.mpo', '.avif']
allowed_extensions = ['.gif', '.jpg', '.jpeg', '.png', '.webp', '.heic', '.mpo', '.avif', '.svg']
def search_for_community(address: str):
@ -649,30 +649,38 @@ def save_icon_file(icon_file, directory='communities') -> File:
if file_ext.lower() == '.heic':
register_heif_opener()
elif file_ext.lower() == '.avif':
import pillow_avif
# resize if necessary
Image.MAX_IMAGE_PIXELS = 89478485
img = Image.open(final_place)
if '.' + img.format.lower() in allowed_extensions:
img = ImageOps.exif_transpose(img)
img_width = img.width
img_height = img.height
if img.width > 250 or img.height > 250:
img.thumbnail((250, 250))
img.save(final_place)
if file_ext.lower() in allowed_extensions:
if file_ext.lower() == '.svg': # svgs don't need to be resized
file = File(file_path=final_place, file_name=new_filename + file_ext, alt_text=f'{directory} icon',
thumbnail_path=final_place)
db.session.add(file)
return file
else:
Image.MAX_IMAGE_PIXELS = 89478485
img = Image.open(final_place)
img = ImageOps.exif_transpose(img)
img_width = img.width
img_height = img.height
# save a second, smaller, version as a thumbnail
img.thumbnail((40, 40))
img.save(final_place_thumbnail, format="WebP", quality=93)
thumbnail_width = img.width
thumbnail_height = img.height
if img.width > 250 or img.height > 250:
img.thumbnail((250, 250))
img.save(final_place)
img_width = img.width
img_height = img.height
# save a second, smaller, version as a thumbnail
img.thumbnail((40, 40))
img.save(final_place_thumbnail, format="WebP", quality=93)
thumbnail_width = img.width
thumbnail_height = img.height
file = File(file_path=final_place, file_name=new_filename + file_ext, alt_text=f'{directory} icon',
width=img_width, height=img_height, thumbnail_width=thumbnail_width,
thumbnail_height=thumbnail_height, thumbnail_path=final_place_thumbnail)
db.session.add(file)
return file
file = File(file_path=final_place, file_name=new_filename + file_ext, alt_text=f'{directory} icon',
width=img_width, height=img_height, thumbnail_width=thumbnail_width,
thumbnail_height=thumbnail_height, thumbnail_path=final_place_thumbnail)
db.session.add(file)
return file
else:
abort(400)
@ -695,6 +703,8 @@ def save_banner_file(banner_file, directory='communities') -> File:
if file_ext.lower() == '.heic':
register_heif_opener()
elif file_ext.lower() == '.avif':
import pillow_avif
# resize if necessary
Image.MAX_IMAGE_PIXELS = 89478485

View file

@ -905,6 +905,7 @@ div.navbar {
}
.post_teaser_image_preview img {
max-width: 100%;
min-width: 150px;
margin-right: 4px;
border-radius: 5px;
height: auto;

View file

@ -501,6 +501,7 @@ div.navbar {
}
img {
max-width: 100%;
min-width: 150px;
margin-right: 4px;
border-radius: 5px;
height: auto;

View file

@ -22,9 +22,9 @@
</div>
{{ render_field(form.description) }}
{{ render_field(form.icon_file) }}
<small class="field_hint">Provide a square image that looks good when small.</small>
<small class="field_hint">{{ _('Provide a square image that looks good when small. SVG is allowed.') }}</small>
{{ render_field(form.banner_file) }}
<small class="field_hint">Provide a wide image - letterbox orientation.</small>
<small class="field_hint">{{ _('Provide a wide image - letterbox orientation.') }}</small>
{{ render_field(form.rules) }}
{{ render_field(form.nsfw) }}
{{ render_field(form.local_only) }}

View file

@ -187,7 +187,7 @@ def make_cache_key(sort=None, post_id=None, view_filter=None):
def is_image_url(url):
common_image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', '.avif']
common_image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', '.avif', '.svg+xml', '.svg+xml; charset=utf-8']
mime_type = mime_type_using_head(url)
if mime_type:
mime_type_parts = mime_type.split('/')