Skip to content

Story 2383: Image reduction for Upload Post Images#2429

Merged
jlchilders11 merged 5 commits into
developfrom
jc/image-reduction-for-uploaded-images
May 21, 2026
Merged

Story 2383: Image reduction for Upload Post Images#2429
jlchilders11 merged 5 commits into
developfrom
jc/image-reduction-for-uploaded-images

Conversation

@jlchilders11
Copy link
Copy Markdown
Collaborator

Issue: #2383

Summary & Context

Adds a helper function to allow for downscaling of uploaded images if they are over the size threshold.

Changes

  • Adds downsize_uploaded_image to news/utils.py, which accepts an uploaded image, downscales it, and returns it for consumption
  • Adds three values to settings values which control this downsizing: DOWNSCALED_HEIGHT, DOWNSCALED_WIDTH, DOWNSCALE_THRESHOLD
  • Adds a test to ensure that the downscaling is reaching our established thresholds.

Self-review Checklist

  • Tag at least one team member from each team to review this PR
  • Link this PR to the related GitHub Project ticket

@julhoang julhoang linked an issue May 13, 2026 that may be closed by this pull request
Copy link
Copy Markdown
Collaborator

@julhoang julhoang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jlchilders11 , please see a couple of change requests below 🙏

Comment thread config/settings.py Outdated
Comment thread news/utils.py Outdated
Comment thread news/utils.py Outdated
Comment thread news/tests/test_utils.py Outdated
Comment thread news/tests/test_utils.py Outdated
Comment thread news/utils.py Outdated
Comment thread news/utils.py Outdated
Comment thread news/utils.py Outdated
@jlchilders11 jlchilders11 requested a review from julhoang May 14, 2026 15:00
@jlchilders11 jlchilders11 force-pushed the jc/image-reduction-for-uploaded-images branch from 44cb65f to afd0b7a Compare May 14, 2026 15:57
Copy link
Copy Markdown
Collaborator

@julhoang julhoang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jlchilders11 ! I've just discovered Pillow has a handy thumbnail method for us to leverage, please see more below.

Comment thread news/utils.py
Comment on lines +71 to +97
if root:
file_name = root
file_name += ".webp"

width, height = im.size
p_width, p_height = None, None # Preferred output image width and height
s_width, s_height = (
settings.DOWNSCALED_IMAGE_WIDTH,
settings.DOWNSCALED_IMAGE_HEIGHT,
) # Settings based preferred width and height

# Scale the preferred width and height in a proportional manner, to not skew the image

# Scale based on the dimension that is further off from preferred dimensions
if width - s_width >= height - s_height:
p_width = s_width
p_height = math.floor((p_width / width) * height)
else:
p_height = s_height
p_width = math.floor((p_height / height) * width)

r_image = im.resize((p_width, p_height))

# Save to a BytesIO, actual file system saving will be handled by the form calling this function
img = BytesIO()
r_image.save(img, format="webp")
img.seek(0)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if root:
file_name = root
file_name += ".webp"
width, height = im.size
p_width, p_height = None, None # Preferred output image width and height
s_width, s_height = (
settings.DOWNSCALED_IMAGE_WIDTH,
settings.DOWNSCALED_IMAGE_HEIGHT,
) # Settings based preferred width and height
# Scale the preferred width and height in a proportional manner, to not skew the image
# Scale based on the dimension that is further off from preferred dimensions
if width - s_width >= height - s_height:
p_width = s_width
p_height = math.floor((p_width / width) * height)
else:
p_height = s_height
p_width = math.floor((p_height / height) * width)
r_image = im.resize((p_width, p_height))
# Save to a BytesIO, actual file system saving will be handled by the form calling this function
img = BytesIO()
r_image.save(img, format="webp")
img.seek(0)
if root:
file_name = root + ".webp"
# Bake EXIF orientation into pixels so portrait phone photos don't end up sideways
im = ImageOps.exif_transpose(im)
# Fits within the bounding box, preserves aspect ratio, never upscales
im.thumbnail(
(settings.DOWNSCALED_IMAGE_WIDTH, settings.DOWNSCALED_IMAGE_HEIGHT),
PImage.Resampling.LANCZOS,
)
# Save to a BytesIO, actual file system saving will be handled by the form calling this function
img = BytesIO()
im.save(img, format="webp")
img.seek(0)

It seems like Pillow offers a handy .thumbnail() method that can handles the math for us – but more important it will not upscale the image like our approach currently permits. The suggested code also adds orientations and resampling. Can we consider using this instead?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. I saw the thumbnail function, but didn't actually realize all the edge cases it pre covered for me. Thanks!

Comment thread news/tests/test_utils.py
from news.utils import downsize_uploaded_image


def test_downscale_image():
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a few more tests here as well? Some cases to consider:

  • Portrait image stays portrait
  • Ratio is preserved
  • Small image doesn't get upscaled
  • New downscale images is smaller than the width and height values that we set in the config.
  • Test png_test.png file gets renamed to png_test.webp

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix for the CI test is now available on develop – would you mind doing a rebase to remove this change from your branch? 😄🙏

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do.

@jlchilders11 jlchilders11 force-pushed the jc/image-reduction-for-uploaded-images branch from 0d34287 to 1b4e83a Compare May 15, 2026 14:02
@jlchilders11 jlchilders11 requested a review from julhoang May 15, 2026 14:40
Copy link
Copy Markdown
Collaborator

@julhoang julhoang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thank you for the updates @jlchilders11 ! 🙌

Copy link
Copy Markdown
Collaborator

@kattyode kattyode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA Approved

@jlchilders11 jlchilders11 force-pushed the jc/image-reduction-for-uploaded-images branch from 085a5ba to de75c12 Compare May 21, 2026 20:05
@jlchilders11 jlchilders11 merged commit 7108006 into develop May 21, 2026
8 checks passed
@jlchilders11 jlchilders11 deleted the jc/image-reduction-for-uploaded-images branch May 21, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Task: Implement Image Reduction for Uploaded Post Images

4 participants