Skip to content

Auto-pad non-square badge uploads to a square (instead of cropping) #1410

Description

@jonfroehlich

Problem

The Awards admin badge is cropped to a fixed 1:1 square on the public Awards page (via image_cropping + Cropper.js, shipped in #1408). For a logo/emblem that isn't already square, the square crop chops off content. Today the workaround is to open an external image editor, pad the image to a square by hand, then upload it — a recurring papercut in the upload flow.

Desired behavior

On upload, if a badge isn't square, offer to pad it to a centered square instead of cropping — adding equal blank margins on the two short sides so the original pixels stay centered and nothing is lost.

  • Transparent margins for alpha-capable formats (PNG/WebP); white margins for JPEG.
  • Keep the existing crop tool available for cases where cropping is what you want.

Design decision (the tricky part)

The cropper's instant preview is client-side, so naive server-side padding would make that preview lie (it would show a center-crop, not the pad). We resolve this with:

  1. Server-side Pillow padding (Pillow is already a dependency) — a small, robust transform; no fiddly browser canvas + file-replacement dance.
  2. A "Pad badge to a square (don't crop)" checkbox in AwardAdminForm (the one bit of signal needed, since the cropper otherwise always forces a square box). Default on for badges.
  3. A CSS-only honest preview: when "pad" is checked, hide the interactive cropper (nothing to crop) and show an object-fit: contain letterbox preview that mirrors exactly how the server will pad. No model/schema change.

When padding is applied, a full-image crop box is stored so the existing crop_corners render path is a no-op on the already-square file.

Scope

Award badge first. The padding helper is field-agnostic, so the same square (245×245) treatment can later extend to Person.image / Sponsor.icon by calling it from their save_model.

Implementation status

Initial implementation drafted on branch 1408-awards-badge-crop:

  • pad_image_to_square() in website/utils/fileutils.py (+ unit tests)
  • AwardAdminForm checkbox + AwardAdmin.save_model wiring (+ integration tests)
  • pad_to_square.js / pad_to_square.css for the live preview

Pending: manual click-through in the admin (wide JPEG → white bars; tall PNG → transparent bars).

Metadata

Metadata

Assignees

No one assigned

    Labels

    AdminAwardsAwards & external recognitions (distinct from paper-level Publication.award)BackendNew Feature

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions