Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Trims the surrounding transparent pixels from a canvas
// MIT http://rem.mit-license.org
function trim(c) {
var ctx = c.getContext('2d'),
copy = document.createElement('canvas').getContext('2d'),
pixels = ctx.getImageData(0, 0, c.width, c.height),
l = pixels.data.length,
i,
bound = {
top: null,
left: null,
right: null,
bottom: null
},
x, y;
for (i = 0; i < l; i += 4) {
if (pixels.data[i+3] !== 0) {
x = (i / 4) % c.width;
y = ~~((i / 4) / c.width);
if (bound.top === null) {
bound.top = y;
}
if (bound.left === null) {
bound.left = x;
} else if (x < bound.left) {
bound.left = x;
}
if (bound.right === null) {
bound.right = x;
} else if (bound.right < x) {
bound.right = x;
}
if (bound.bottom === null) {
bound.bottom = y;
} else if (bound.bottom < y) {
bound.bottom = y;
}
}
}
var trimHeight = bound.bottom - bound.top,
trimWidth = bound.right - bound.left,
trimmed = ctx.getImageData(bound.left, bound.top, trimWidth, trimHeight);
copy.canvas.width = trimWidth;
copy.canvas.height = trimHeight;
copy.putImageData(trimmed, 0, 0);
// open new window with trimmed image:
return copy.canvas;
}
@joloco

This comment has been minimized.

Show comment
Hide comment
@joloco

joloco Feb 13, 2012

Great code, just what I needed! The only thing I changed was that bound.bottom and bound.right both need incrementing by one after the loop, or the bottom-most and right-most rows of pixels get trimmed off.

joloco commented Feb 13, 2012

Great code, just what I needed! The only thing I changed was that bound.bottom and bound.right both need incrementing by one after the loop, or the bottom-most and right-most rows of pixels get trimmed off.

@jamespcole

This comment has been minimized.

Show comment
Hide comment
@jamespcole

jamespcole Apr 11, 2013

Awesome, thanks for that

Awesome, thanks for that

@honsuales

This comment has been minimized.

Show comment
Hide comment
@honsuales

honsuales Apr 26, 2013

Hello remy, just wondering if is possible to add an example.
Thank you for the code.

Hello remy, just wondering if is possible to add an example.
Thank you for the code.

@smaier

This comment has been minimized.

Show comment
Hide comment
@smaier

smaier Jun 11, 2014

thanks a lot! Great

smaier commented Jun 11, 2014

thanks a lot! Great

@EricJLD

This comment has been minimized.

Show comment
Hide comment
@EricJLD

EricJLD Jun 15, 2014

Hello Remy, your tool seems to be what I am looking for. great I hv been spending my wknd browsing over many sites.
however, i'm very new in html/js ...
may I you to add some more lines to make it a full concrete example with an image file that I could copy/past and make work. then, I will adapt to my need ? sorry for this request but it's necessary for me to get started. thk you very much in avance. Eric

EricJLD commented Jun 15, 2014

Hello Remy, your tool seems to be what I am looking for. great I hv been spending my wknd browsing over many sites.
however, i'm very new in html/js ...
may I you to add some more lines to make it a full concrete example with an image file that I could copy/past and make work. then, I will adapt to my need ? sorry for this request but it's necessary for me to get started. thk you very much in avance. Eric

@drumfiend21

This comment has been minimized.

Show comment
Hide comment
@drumfiend21

drumfiend21 Jun 18, 2015

Using this in a school project. Thank you very much

Using this in a school project. Thank you very much

@br750

This comment has been minimized.

Show comment
Hide comment
@br750

br750 Nov 27, 2015

Awesome, just too much guy ;-)

br750 commented Nov 27, 2015

Awesome, just too much guy ;-)

@onassar

This comment has been minimized.

Show comment
Hide comment
@onassar

onassar Feb 5, 2016

@joloco Any chance you have your code for this, so many years later?

onassar commented Feb 5, 2016

@joloco Any chance you have your code for this, so many years later?

@tomswatermelon

This comment has been minimized.

Show comment
Hide comment
@tomswatermelon

tomswatermelon Jul 3, 2016

Man this saves my life, thanks!

Man this saves my life, thanks!

@WingMrL

This comment has been minimized.

Show comment
Hide comment
@WingMrL

WingMrL Dec 2, 2016

Thank you very much !

WingMrL commented Dec 2, 2016

Thank you very much !

@huanle0610

This comment has been minimized.

Show comment
Hide comment
@huanle0610

huanle0610 Feb 4, 2017

Wooh, awesome!
Working with konvajs, I use it like this:

window.open(trim(layer.children[77].toCanvas()).toDataURL());

Wooh, awesome!
Working with konvajs, I use it like this:

window.open(trim(layer.children[77].toCanvas()).toDataURL());
@allisonc-timeless

This comment has been minimized.

Show comment
Hide comment
@allisonc-timeless

allisonc-timeless May 22, 2017

This isn't working for me, it is only trimming 1px on each dimension.

This isn't working for me, it is only trimming 1px on each dimension.

@holethienthanh

This comment has been minimized.

Show comment
Hide comment
@holethienthanh

holethienthanh Jun 7, 2017

Thanks a lot.

Thanks a lot.

@peterchibunna

This comment has been minimized.

Show comment
Hide comment
@peterchibunna

peterchibunna Jun 7, 2017

Awesome and intelligent code! I just modified it to add padding to the image cropped.

Awesome and intelligent code! I just modified it to add padding to the image cropped.

@timdown

This comment has been minimized.

Show comment
Hide comment
@timdown

timdown Jul 24, 2017

Thanks, just what I needed. One tiny improvement: you could use the original canvas element's ownerDocument rather than document to create the copy so that they both exist in the same document. This could be important if your canvas comes from an iframe which has different fonts loaded to the main document and you want to draw text on the trimmed canvas (which happens to be exactly what I want to do).

timdown commented Jul 24, 2017

Thanks, just what I needed. One tiny improvement: you could use the original canvas element's ownerDocument rather than document to create the copy so that they both exist in the same document. This could be important if your canvas comes from an iframe which has different fonts loaded to the main document and you want to draw text on the trimmed canvas (which happens to be exactly what I want to do).

@timdown

This comment has been minimized.

Show comment
Hide comment
@timdown

timdown Jul 25, 2017

Also, this crops one pixel too much on the right and bottom. You need to add one to bounds.bottom and bounds.right (or to trimWidth and trimHeight).

timdown commented Jul 25, 2017

Also, this crops one pixel too much on the right and bottom. You need to add one to bounds.bottom and bounds.right (or to trimWidth and trimHeight).

@timdown

This comment has been minimized.

Show comment
Hide comment
@timdown

timdown Jul 26, 2017

I created my own with some optimizations to minimize the number of pixels examined:

https://gist.github.com/timdown/021d9c8f2aabc7092df564996f5afbbf

timdown commented Jul 26, 2017

I created my own with some optimizations to minimize the number of pixels examined:

https://gist.github.com/timdown/021d9c8f2aabc7092df564996f5afbbf

@ranasoyab

This comment has been minimized.

Show comment
Hide comment
@ranasoyab

ranasoyab Nov 29, 2017

Thank you very much !

Thank you very much !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment