gSkinner - Home

Reducing File Size for Images With Alpha Channels

Posted on August 29, 2012 by Grant Skinner

We’ve been building a lot of spritesheets and other images for use in HTML5 projects. To preserve alpha channels, you need to use PNG32, which can get pretty large for some types of content because it’s a lossless compression format.

I wanted to find a way to reduce these file sizes, so that games and other experience would load more quickly. Ultimately I settled on a solution that separates an image into two parts: a JPG with all of the RGB information, and a PNG32 with the alpha channel. In my testing, the end results vary wildly – some content is larger when split, but some content can see a reduction in size of up to 70%. This is can have a pretty significant effect when applied to a 2MB sprite sheet image!

To enable this, I added a utility method in EaselJS that takes these two images and merges them back into a single canvas, which can be used for sprite sheets, drawn to other canvases, added to the DOM, or used as an image source via toDataURL(). The great thing is, it runs REALLY fast (a few milliseconds for most large images), because it leverages composite operations.

var combinedCanvas = SpriteSheetUtils.mergeAlpha(rgbImage, alphaImage);

For initial testing, I prepared my images using Photoshop, but this was slow, time consuming, and cumbersome. To make the process easier, I wrote a simple AIR application codenamed “Omega” (as in, alpha and omega – such boundless wit!). It will prepare multiple images at a time, and display a report showing the original and total resulting sizes, so you can decide which assets to use it on.

It’s currently very barebones, and requires you to do everything via the command line. In some ways, this is kind of nice – you can create batch files or commands to quickly run it on specific files or folders of images – but I plan to add a UI soon. I’m also planning to open source it the not too distant future, but I thought I should share it in the interim so others can use it.

You can grab “Omega” here. It comes with a text file that describes all of the available arguments and shows some examples. It works great with Zoë or your spritesheet creation tool of choice.

One important note: if you’re using Omega on OSX, you’ll need to quit the application before running it a second time. For some reason AIR apps on OSX do not receive parameters with invocation events if they are already open.

Follow @gskinner on Twitter for more news and views on interactive media.

Rather than jpeg compressing an image with black background, I'd suggest to repeatedly blur the image whilst copying the original over the top each time, prior to encoding. in psuedocode:

copy = image.clone();
for( i = 0 to 10){
image = image.blur();
image = image.overlay(copy)
jpg = image.colorchannel.toJpeg()
png = copy.alphachannel.toPng()

When the image is decompressed all the blur will disappear because it is under fully transparent alpha.

This will result in a color channel that is far more suitable for jpg encoding as it has no sharp edges around the image boundary. You'll find you can use lower jpg quality (thus smaller filesize) without introducing black halo artifacts around the decompressed image.

Also, the alpha channel can be compressed as png8, which will be smaller too.

Regards, Jake

Posted by: Jake Lewis on Aug 30, 2012 9:07am

Why not just use ImageAlpha?

Posted by: Øyvind Nordhagen on Aug 30, 2012 4:42pm

I was messing with this today... you can also get further savings (30-40% of the alpha png) by using pngcrush with the -c 4 option.

Posted by: Matt C on Dec 12, 2012 12:32pm URL:

If the alpha png only contains the two colors transparent and black, then you can reduce it quite a lot using `pngquant 2 image.png` making it a png8 with a 2-colro pallette. Then run pngcrush or optipng on it to further improve the compression.

If there are more colors, but still less than 256, you can detect the number of colors with a histogram before you pngquant it down to that number of colors. We use that technique in

Posted by: Peter Müller on Dec 18, 2012 3:50am URL:

[...] your image formats and compression settings head on. Save backgrounds as JPG. Use tools like Omega to blend JPG compression with alpha channels, or ImageAlpha to use indexed PNGs with full alpha [...]

Posted by: Build HTML5 using Best Pr… on Dec 18, 2012 7:30am URL:…

[...] your image formats and compression settings head on. Save backgrounds as JPG. Use tools like Omega to blend JPG compression with alpha channels, or ImageAlpha to use indexed PNGs with full alpha [...]

Posted by: Build HTML5 using Best Pr… on Dec 21, 2012 2:45pm URL:…

[...] 「Zoë」の他にも、「Toolkit for CreateJS」、「OMEGA」など、いくつかのツールが紹介されています。 [...]

Posted by: HTML5リッチコンテ… on Jan 12, 2013 11:35pm URL:…

btw jpeg rate could probably be improved by some kind of "glow" around the edge, letting colors "fade" into the darkness instead of sharp edge.

Posted by: makc on Jan 17, 2013 10:16am URL:

[...] Addressing image formats with the head. Save as JPG backgrounds. Use tools such as Omega to get the JPG compression with alpha channel, or ImageAlpha to use PNG with 256 colors with [...]

Posted by: HTML5 games: create video… on Feb 6, 2013 2:55pm URL:…

The mergeAlpha function in the spriteSheetUtil doesnt work well when used in Chrome. I believe this is because of the destination-in Global composite operation setting.
It seems like destination-in is not supported well in Chrome Browser (Tested in Chrome 25 ).

Is there any other approach to merge alpha and RGB images?

Posted by: Srinivasan on Mar 12, 2013 7:12am

Thanks for creating this tool. But i see risk in using this mergeAlpha approach. I've just found ( Mac ) and which are doing great job.

They create 8bit PNG with smooth alpha.

Posted by: appBauer on Mar 19, 2013 7:14am URL:

[...] new tool by, Omega, uses a separate alpha channel to provide the file-saving of JPEG images with the alpha [...]

Posted by: Games Galore: Building At… on Mar 29, 2013 2:30am URL:…

One more tool

Posted by: Pol on Apr 19, 2013 10:18pm

Leave a Reply

Your email is never published nor shared.

You may use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>