Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Feature request: trim transparent borders of PNG images (single & batch, in-place)

Chiusa
#332 6 commenti 0 reazioni 2 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@cre8ive-marketing ci sta già lavorando.

Dal 22/10/2026.

  • #481 di @cre8ive-marketing — integrata

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

enhancement

What would you like File to do?
Add a "Trim transparent borders" action for PNG images:

  • Runs on a single selected PNG, or on all PNGs inside a selected folder (with an optional "include subfolders" toggle)
  • Crops away the fully-transparent padding around the visible content and overwrites the file in place
  • Shows a brief summary afterwards: how many cropped / skipped (and why) / failed
  • Ideally also exposed on the command line (e.g. file --trim-png [-r]) so it can be scripted
    Scope suggestion: PNG only. WebP with alpha would be a nice bonus; JPEG can be left out since it has no alpha channel.
    Why / when would you use it?
    PNGs exported from Photoshop, Figma, slicing tools or renderers almost always carry a large transparent margin. Once such a file lands in a document, a web page or a UI mockup, the image box no longer matches the visible content, so you end up re-aligning and cropping by hand — one file at a time.
    My own case: I process dozens of product-render PNGs every day, and right now I depend on a separate standalone utility — one that registers its own Explorer context-menu entry — purely for this single action. It is by far the most frequent reason I have to leave File, so having it built in would remove an entire tool from my machine.
    Ideas for how it could work? (optional — engine or library suggestions welcome)
    The core is roughly 40 lines of image code and needs no new heavyweight dependency.
    Algorithm:
  1. Load the PNG and obtain its alpha channel.
  2. Threshold the alpha first — treat alpha < 8 as fully transparent. Using alpha != 0 looks simpler but fails in practice: one stray pixel with alpha = 1 on the border makes the bounding box collapse to the whole canvas, so the image "cannot be trimmed" and the user concludes the feature is broken.
  3. Compute the bounding box of the thresholded alpha.
  4. bbox empty → fully transparent, skip. bbox == full canvas → nothing to trim, skip (and do not rewrite the file).
  5. Crop to bbox.
    Four pitfalls worth handling up front — all of them show up in real asset folders:
  • Indexed / palette PNGs (8-bit P mode with a tRNS transparency chunk) have no separate alpha channel, so a naive "does it have an alpha band?" check classifies them as no transparency and silently skips them. Check the tRNS / transparency metadata, or convert to RGBA before testing.
  • Metadata: preserve DPI and ICC profile when saving. Dropping DPI turns a 300 DPI asset into 96 DPI, which is a real problem for print and design handoff.
  • Write atomically: never save() straight onto the original path — it truncates the file first, so a crash, a full disk or a power loss destroys the original image. Write to a temp file in the same directory, then rename over it. An optional "keep a copy in ./.backup" toggle is welcome.
  • Leave untouched files untouched: skipping no-op rewrites keeps mtimes stable, which matters for sync tools and backup software.
    One UX detail: if the action runs on a folder and everything gets skipped, say so explicitly in the summary. Silence reads as a bug report waiting to happen.
    Reference implementation (Python + Pillow):
    import os
    from PIL import Image

def trim_png(path, thresh=8):
with Image.open(path) as im:
im.load()
info = dict(im.info)

    # 1. resolve alpha, including palette images with a tRNS chunk
    if im.mode == 'P':
        if 'transparency' not in info:
            return 'skip: no alpha'
        im = im.convert('RGBA')
    elif 'A' in im.getbands():
        im = im if im.mode == 'RGBA' else im.convert('RGBA')
    else:
        return 'skip: no alpha'

    # 2. threshold: ignore near-invisible noise pixels
    mask = im.split()[-1].point(lambda v: 255 if v >= thresh else 0)

    # 3/4. bounding box
    bbox = mask.getbbox()
    if bbox is None:
        return 'skip: fully transparent'
    if bbox == (0, 0, im.width, im.height):
        return 'skip: nothing to trim'

    # 5. crop, keeping DPI and colour profile
    out = im.crop(bbox)
    kw = {'format': 'PNG', 'optimize': True}
    if info.get('dpi'):
        kw['dpi'] = info['dpi']
    if info.get('icc_profile'):
        kw['icc_profile'] = info['icc_profile']

    tmp = path + '.tmp'          # same directory -> same volume
    out.save(tmp, **kw)
    os.replace(tmp, path)        # atomic on Windows and POSIX

return 'ok: %dx%d -> %dx%d' % (im.width, im.height, out.width, out.height)

Happy to send a PR if the direction sounds right.

Lingua principale
C#
Stelle
3.6k
Fork
192
Merge medio
5h 40m
PR unite (30g)
210

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di KnifeLemon/Filee

Tutte le issue di KnifeLemon/Filee

Issue simili

Altre issue su C#

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.