Feature request: trim transparent borders of PNG images (single & batch, in-place)
Maintainer thường phản hồi trong vòng 1 ngày
@cre8ive-marketing đang làm issue này rồi.
Từ ngày 22/10/2026.
- #481 của @cre8ive-marketing — đã merge
Đánh giá
Issue này chưa được đánh giá.
Mô tả
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.
- Ngôn ngữ chính
- C#
- Star
- 3.6k
- Fork
- 192
- Merge trung bình
- 5 giờ 40 phút
- Pull request đã merge (30 ngày)
- 210
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của KnifeLemon/Filee
-
[Bug] Interactive toggle inside Theme preview card is completely unresponsive in SettingsCó thể đã có người làm @Saad-elnagar đã nhận 2 ngày trước. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
KnifeLemon/Filee#363 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Format request: .midĐang mởformats
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 20/100
KnifeLemon/Filee#501 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: 转换一个ansi中文txt文件到pdf,全部中文乱码成韩文。Có thể đã có người làm @cre8ive-marketing đã nhận hôm nay. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 25/100
KnifeLemon/Filee#491 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Format request: .vid to .mp4Đang mởformats
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 48/100
KnifeLemon/Filee#490 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
CAD: choose the DWG/DXF version to write (e.g. AutoCAD 2013)Có thể đã có người làm @cre8ive-marketing đã nhận hôm nay. Đang mởenhancement
KnifeLemon/Filee#489 · 3 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của KnifeLemon/Filee
Issue tương tự
-
dev/release: verify-release-candidate.sh runs 0 Java tests with Debian's MavenCó thể đã có người làm @kou đã nhận hôm nay. Đang mởType: bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
apache/arrow-adbc#4947 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
microsoft/fluentui-blazor#5535 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 74/100
AvaloniaUI/Avalonia#22582 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
:watch: Not Triaged CAC
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/AspNetCore.Docs#38001 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
HTTP logging truncates catch-all route parameters in the formatted request pathCó thể đã có người làm @johnkaram02 đã nhận hôm nay. Đang mởarea-telemetry untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/extensions#7883 ·
Maintainer thường phản hồi trong vòng 1 ngày