Awards badge: auto-pad non-square uploads to a square (#1410)#1411
Merged
Conversation
The Awards badge is cropped to a 1:1 square on the public page; for a non-square logo that chops off content. Add a "Pad badge to a square (don't crop)" option (default on) that pads the upload to a centered square -- white margins for JPEG, transparent for PNG/WebP -- instead of cropping. This replaces the editor's manual pre-upload padding step. - pad_image_to_square() in fileutils.py: Pillow padding, EXIF-aware, format-preserving. Padding always re-encodes (you can't insert margin pixels into a compressed JPEG/WebP stream): JPEG at fixed quality=92, WebP saved lossless so a lossless source isn't degraded, PNG/GIF are lossless anyway, and already-square uploads return None (untouched). Returns a full-image crop box so crop_corners is a no-op on the result. - AwardAdminForm checkbox + AwardAdmin.save_model wiring; pads only a freshly uploaded, non-square badge. No model/schema change. - pad_to_square.js/.css: hide the cropper and show an honest object-fit:contain preview while padding; toggled via a pad-mode class on the form, so no load-order dependency on ml_cropper.js. - Tests: padding logic (white/transparent/centering/webp/square no-op), save_model wiring, and the admin add-page render. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an option to pad a non-square Award badge upload to a centered square instead of cropping it — eliminating the editor's manual "pad it in an external tool before uploading" step.
The badge is cropped to a 1:1 square on the public Awards page, so a non-square logo otherwise gets content chopped off. Now a "Pad badge to a square (don't crop)" checkbox (default on) pads the upload with white margins (JPEG) or transparent margins (PNG/WebP), keeping the whole image centered.
How / why
The cropper's preview is client-side, so naive server-side padding would make the preview lie. Resolved with:
object-fit: containletterbox preview mirrors exactly what the server saves.When padding applies, a full-image crop box is stored so the existing
crop_cornersrender path is a no-op.Image format & compression notes
Padding always re-encodes the image — you can't insert margin pixels into a compressed JPEG/WebP stream (DCT/compressed blocks, not addressable pixels), so Pillow decodes to a bitmap, we paste centered, and the whole image is encoded again.
quality=92. We don't reuse the source's quantization tables — Pillow'squality="keep"only works on an unmodified image, and pasting onto a larger canvas modifies it. One extra, visually negligible generation of compression for the flat logos badges usually are.lossless=Trueso a lossless source isn't silently degraded (Pillow's WebP default is lossy q80).return None) — original bytes never touched.Scope
Award badge first.
pad_image_to_square()is field-agnostic, so the same treatment can later extend toPerson.image/Sponsor.icon.Files
website/utils/fileutils.py—pad_image_to_square()website/admin/award_admin.py— checkbox,save_modelwiring,Mediawebsite/static/website/js/pad_to_square.js+css/pad_to_square.css— toggle + previewwebsite/tests/test_pad_image_to_square.py— 8 testsTesting
python manage.py test website.tests.test_pad_image_to_square --settings=makeabilitylab.settings_test→ 8 passing: padding logic (white/transparent margins, centering, WebP lossless, square no-op),save_modelwiring, and an end-to-end admin add-page render. Maintainer verified the toggle/preview behavior in the local admin.Screenshot
Closes #1410.
🤖 Generated with Claude Code