claus / as3swf

Low level Actionscript 3 library to parse, create, modify and publish SWF files.
MIT License
525 stars 127 forks source link

- Implemented AS3GraphicsDataShapeExporter.beginBitmapFill() #32

Closed soywiz closed 10 years ago

soywiz commented 10 years ago

Usage: ImageDecoderAsync.decodeAsync(swf, function(imageDecoderAsync:ImageDecoderAsync):void { var exporter:AS3GraphicsDataShapeExporter = new AS3GraphicsDataShapeExporter(swf, imageDecoderAsync); shape.export(exporter); })

soywiz commented 10 years ago

I have seen this in the roadmap: "Provide convenience methods to import/export various types of assets (bitmaps, sounds, fonts, ..)"

Maybe the "ImageDecoderAsync" could be something like:

interface IGetDecodedAssets {
   function getBitmapDataFromCharacterId(characterId:int):BitmapData;
   function getSoundFromCharacterId(characterId:int):Sound;
}

class DecodeAssetsAsync {
   static public function getDecodedAssetsFromSwf(swf:SWF, onDone:Function/*<IGetDecodedAssets;>*/):void;
}

The only way to decode image files without external dependencies is the Loader, and that is performed in an async fashion.


I have just seen the TagDefineBits.exportBitmapData. Other way could be make the SWFShape.export method async. Something like:

SWFShape.exportAsync(handler:IShapeExporter, onDone:Function):void;

or using promises ( https://github.com/CodeCatalyst/promise-as3 ):

SWFShape.exportAsync(handler:IShapeExporter):Promise;

But IShapeExporter interface should have all methods asynchoronous. then the beginBitmapFill could call the TagDefineBits.exportBitmapData and wait it to be completed. That would be lazy loading instead of the solution I proposed. Though the solution I proposed is simple probably wouldn't work very good with really large files.

claus commented 10 years ago

Carlos, i appreciate your thoughts on this, thanks! I already thought a lot on whether or not to provide functionality that exports bitmaps for bitmap fills (and if yes, how). I am still undecided if this should be a part of as3swf at all. I actually have code somewhere that packs embedded bitmaps together into an in-memory SWF, with appropriate stub base classes (created by as3commons bytecode) and export symbols set up, so you only need one Loader to load all of the bitmap assets contained in a SWF. However that does not really solve the common use case to export JPEG/PNG images to be used outside Flash (for example for SVG, Objective-C etc exporters). For DefineBitsLossless or DefineBitsJPEG with alpha, you'd also need a PNG encoder or similar, to export to a proper image format. I'm reluctant to include all that in as3swf. Of course you could argue that this last step could be done outside as3swf, but then where do you draw the line? I think the best solution would be to keep all that outside as3swf, in the form of a separate utility library that people can use if they really need this functionality.

soywiz commented 10 years ago

Thanks for the reply!

I extracted the code I made from as3swf and improved it a little: using promises, and handling the JPEG3 tag and writting the alpha channel, and properly removing even handlers.

Also, new versions of as3 (11.3+) include a way to encode to PNG and JPEG: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#encode()

bitmapData.encode(new PNGEncoderOptions());

I'm using that to generate png files with the BitmapData stuff, and then generating a zip file with all the generated assets.

I agree with you that it's probably out of the scope as3swf project should be. Maybe could you create a as3swf-exporters project? I would be happy to contribute to that project too.

Regarding to this pull request, I'm going to close it. But if you end creating a project for exporters, please tell me :)

Thanks for your great project and keep up the good work!