Jaid
Jaid

Reputation: 13

How do I trim transparent borders from my image in an efficient way?

I want to automatate the process of trimming transparent edges from PNG images with Node.js, but rather with either with a CLI tool (called by child_process) or a Node module with native bindings than a pure JavaScript implementation for performance reasons.

This sounds like a fairly simple task, but I am searching for weeks without any results that fit my needs.

I currently use Sharp and GraphicsMagick for a complex chain of image manipulations, but because I didn't find a tool for transparency trimming, I wrote a custom Jimp plugin that handles the trimming jobs in a rather inefficient way, but it's still working.

Here is an example input image:

And an expected output image:

I want to get rid of Jimp though.

Upvotes: 1

Views: 3325

Answers (1)

jcupitt
jcupitt

Reputation: 11210

libvips, the image processing library used by sharp, has find_trim.

In your case you only want to test the alpha channel (band 3), so extract that and search for the bounding box of values more than 200 from 0 (ie. near solid)::

$ vips extract_band test-transparency.png x.png 3
$ vips find_trim x.png --background 0 --threshold 200
0
0
445
475

And that's left/top/width/height of the area you want. You can crop that out of your original image with:

$ vips crop test-transparency.png y.png 0 0 445 475

To make:

enter image description here

You can do it as a one-liner with:

$ vips crop test-transparency.png y.png $(vips extract_band test-transparency.png x.png 3; vips find_trim x.png --background 0 --threshold 200)

You can make it a little more efficient in Python:

#!/usr/bin/python3

import sys
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1])
left, top, width, height = image[3].find_trim(background=0, threshold=200)
image = image.crop(left, top, width, height)
image.write_to_file(sys.argv[2])

And shell out to that. Of course, you might not want to add py as a dependency.

Upvotes: 1

Related Questions