Feature request: trim transparent borders of PNG images (single & batch, in-place)
I maintainer di solito rispondono entro 1 giorno
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
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:
- Load the PNG and obtain its alpha channel.
- 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.
- Compute the bounding box of the thresholded alpha.
- bbox empty → fully transparent, skip. bbox == full canvas → nothing to trim, skip (and do not rewrite the file).
- 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
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di KnifeLemon/Filee
-
[Bug] Interactive toggle inside Theme preview card is completely unresponsive in SettingsForse già presa @Saad-elnagar l’ha presa 2 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
KnifeLemon/Filee#363 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Format request: .midApertaformats
Difficoltà 5/5 Più di una settimana Idoneità per principianti 20/100
KnifeLemon/Filee#501 ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: 转换一个ansi中文txt文件到pdf,全部中文乱码成韩文。Forse già presa @cre8ive-marketing l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 25/100
KnifeLemon/Filee#491 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Format request: .vid to .mp4Apertaformats
Difficoltà 2/5 1-3 ore Idoneità per principianti 48/100
KnifeLemon/Filee#490 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
CAD: choose the DWG/DXF version to write (e.g. AutoCAD 2013)Forse già presa @cre8ive-marketing l’ha presa oggi. Apertaenhancement
KnifeLemon/Filee#489 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di KnifeLemon/Filee
Issue simili
-
area-multitenancy area-security p1-recommended priority-high technical-debt
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
kind/enhancement Provider Upgrade pulumi/pulumi-azure R1 Task
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
pulumi/pulumi-azure#3669 ·
-
type/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
webclient does not startForse già presa @PawelTroka l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
PawelTroka/Computator.NET#257 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
eriknihlen/OpenAC#255 ·
I maintainer di solito rispondono entro 1 giorno