Permalink
Browse files

Apply alpha mask to JPEGs.

  • Loading branch information...
mbebenita committed Jan 17, 2013
1 parent ef4a7b5 commit 6ec12ffbc4c6ca3ce65eeb940b50172744ad2abd
Showing with 29 additions and 43 deletions.
  1. +28 −2 src/flash/display/Loader.js
  2. +1 −41 src/swf/image.js
@@ -671,10 +671,36 @@ var LoaderDefinition = (function () {
var img = new Image;
var imgPromise = new Promise;
img.onload = function () {
- imgPromise.resolve();
+ if (symbol.mask) {
+ // Make a temporary canvas, write the symbol image into it and apply
+ // the symbol mask, then load back the image as a png so that its alpha
+ // channel is set.
+ var maskCanvas = document.createElement('canvas');
+ maskCanvas.width = symbol.width;
+ maskCanvas.height = symbol.height;
+ var maskContext = maskCanvas.getContext('2d');
+ maskContext.drawImage(img, 0, 0);
+ var maskImageData = maskContext.getImageData(0, 0, symbol.width, symbol.height);
+ var maskImageDataBytes = maskImageData.data;
+ var symbolMaskBytes = symbol.mask;
+ var width = maskImageData.width;
+ var height = maskImageData.height;
+ for (var y = 0; y < height; y++) {
+ for (var x = 0; x < width; x++) {
+ var p = y * width + x;
+ maskImageDataBytes[(p << 2) + 3] = symbolMaskBytes[p];
+ }
+ }
+ maskContext.putImageData(maskImageData, 0, 0);
+ img.onload = function () {
+ imgPromise.resolve();
+ };
+ img.src = maskCanvas.toDataURL("image/png");
+ } else {
+ imgPromise.resolve();
+ }
};
img.src = 'data:' + symbol.mimeType + ';base64,' + btoa(symbol.data);
-
promiseQueue.push(imgPromise);
className = 'flash.display.BitmapData';
props.img = img;
View
@@ -55,47 +55,7 @@ function defineImage(tag, dictionary) {
var alphaData = tag.alphaData;
if (alphaData) {
assert(width && height, 'bad image', 'jpeg');
-
- var ihdr =
- toString32(width) +
- toString32(height) +
- '\x08' + // bit depth
- '\x03' + // color type
- '\x00' + // compression method
- '\x00' + // filter method
- '\x00' // interlace method
- ;
-
- var stream = createInflatedStream(alphaData, width * height);
- var bytes = stream.bytes;
- var literals = '';
- for (var i = 0; i < height; ++i) {
- stream.ensure(width);
- var begin = i * width;
- var end = begin + width;
- var scanline = slice.call(bytes, begin, end);
- literals += '\x00' + fromCharCode.apply(null, scanline);
- }
- var len = literals.length;
- var nlen = ~len & 0xffff;
- var idat =
- '\x78' + // compression method and flags
- '\x9c' + // flags
- '\x01' + // block header
- toString16Le(len) +
- toString16Le(nlen) +
- literals +
- toString32(adler32(literals)) // checksum
- ;
-
- mask =
- '\x89\x50\x4e\x47\x0d\x0a\x1a\x0a' + // signature
- createPngChunk('IHDR', ihdr) +
- plte +
- trns +
- createPngChunk('IDAT', idat) +
- createPngChunk('IEND', '')
- ;
+ mask = createInflatedStream(alphaData, width * height).bytes;
}
if (tag.incomplete) {
var tables = dictionary[0];

3 comments on commit 6ec12ff

Contributor

magcius replied Jan 17, 2013

getImageData/putImageData is slow, so we should probably use drawImage and a composition operator. See:

http://magcius.mecheye.net/flash/shumway/mask.html

Contributor

mbebenita replied Jan 17, 2013

Then we need to create an image out of the symbol mask. Not sure how to do that without getImageData / putImageData

Contributor

tobytailor replied Jan 17, 2013

The mask is already exported as PNG data.

Please sign in to comment.