# PNGEncoder2 **Repository Path**: mirrors_cameron314/PNGEncoder2 ## Basic Information - **Project Name**: PNGEncoder2 - **Description**: A better PNG encoder for Flash - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-24 - **Last Updated**: 2026-01-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Overview ======== This is the quick-start guide to my PNGEncoder2 library, which compresses BitmapData objects into PNG files (stored in ByteArray objects). For a more in-depth explanation of how it works check out my [blog post][blog] about it. Features ======== - **Blazing fast performance**: Written in [haXe][haxe] and highly tuned for speed, it can outperform the [as3corelib PNGEncoder][encoder] by up to 5x (on the FAST setting)! This is made possible by the **custom DEFLATE library** I wrote from scratch specifically for this encoder. - **Compression options**: Also made possible by my custom DEFLATE implementation, you can now choose between compression levels: FAST, NORMAL, and GOOD (and UNCOMPRESSED too, but...). - **True asynchronous encoding**: Most other asynchronous PNG encoders do the conversion from bitmap data to PNG data asynchronously, then call ByteArray.compress() at the end -- which is a long, synchronous operation that can take half the total encoding time or more. (An exception is the cool [In-Spirit PNG encoder][in-spirit], but its asynchronous mode is amazingly slow, and the SWC weighs in at over 100KB.) Mine does completely smooth encoding, asynchronously (with progress events!) and scales to a target FPS without wasting any cycles idling. - **Large image support**: Can compress ridiculously large images on-the-fly, since it does the work in manageable chunks (when done asynchronously) instead of all at once. There is no single-step bottleneck. - **Opaque bitmap support**: If your BitmapData is not transparent, then it will be automatically encoded using the (generally smaller) 24-bit PNG format, otherwise the 32-bit format is used. (Note that transparency is detected via the `transparent` property of the BitmapData object, and not by scanning every pixel, which would be too slow.) - **Open source**: Use the haXe classes if you have a haXe project, or build against an SWC if you have an AS3 project. See the licenses at the top of [PNGEncoder2.hx][PNGEncoder2.hx] and [DeflateStream.hx][DeflateStream.hx] (both have separate, but similarly permissive, licenses). Usage ===== PNGEncoder2 supports both synchronous (fast but freezes the UI while it encodes) and asynchronous PNG encoding (a smidgeon slower, but can maintain a target FPS). ### Synchronous example: ```as3 var bmp : BitmapData = ...; // The bitmap you want to encode var png : ByteArray; // Variable to store the result PNGEncoder2.level = CompressionLevel.FAST; // Optional. Defaults to FAST png = PNGEncoder2.encode(bmp); ``` ### Asynchronous example: ```as3 var bmp : BitmapData = ...; // The bitmap you want to encode PNGEncoder2.level = CompressionLevel.FAST; // Optional. Defaults to FAST var encoder : PNGEncoder2 = PNGEncoder2.encodeAsync(bmp); encoder.targetFPS = 12; // Optional. Defaults to 20. Lower FPSs yield faster compression // Because the encoder is guaranteed to fire the COMPLETE event // after at least one frame, it's safe to attach the listener after // starting the encoding (as long as it's done before the next frame) encoder.addEventListener(Event.COMPLETE, function (e) { var png : ByteArray = encoder.png; }); // encoder also dispatches ProgressEvent.PROGRESS events if you // want to be notified of progress ``` ### Memory-constrained environments: If you're working in a memory-constrained environment, or with truly huge images, the asynchronous method is usually the best choice as it encodes the image one chunk at a time, and therefore requires much less working memory. After encoding an image, however, the working memory is not freed. This is not a memory leak, but rather an optimization to speed up the next encoding (the memory is reused, which among other things eliminates the need to recalculate the CRC tables each time). With large images, or low available memory, this may be undesirable. To free the working memory, simplpy call `PNGEncoder2.freeCachedMemory()` after each encoding is complete. This will reduce the resident memory usage to near zero from what could otherwise be potentially several kilobytes or even megabytes (what a savings!). ### Bonus: PNG decoding Update: Support for synchronous decoding of PNGs that were created using PNGEncoder2 has been added: ```as3 var bmp : BitmapData = ...; var png : ByteArray = PNGEncoder2.encode(bmp); bmp = PNGEncoder2.decode(png); // Round-trip back to BitmapData ``` Decoding is about twice as fast as encoding, though it should be stressed that only PNGEncoder2 PNGs can be decoded properly, not arbitrary PNGs. The advantage is that decoding is faster than using the built-in flash.display.Loader object, at the cost of reduced flexibility; if you need to decode arbitrary PNG files, or you want to decode asynchronously, use the Loader as usual: ```as3 var png : ByteArray = ...; // From a file or encoded PNG ByteArray var loader : Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (e) { var bmp : BitmapData = new BitmapData((int)loader.width, (int)loader.height, true, 0x00FFFFFF); bmp.draw(loader); // Write the decoded PNG to a bitmap data object }); loader.loadBytes(png); ``` ### Bonus: Metadata support Update: Support for encoding text metadata into the generated PNG has been added: ```as3 var bmp : BitmapData = ...; var metadata : Object = { }; metadata[PNGKeywords.TITLE] = "My PNG"; metadata["Custom key"] = "Chunky bacon!"; var png : ByteArray = PNGEncoder2.encodeWithMetadata(bmp, metadata); ``` Every key-value pair in the given metadata object will be encoded into the PNG as either a tEXt chunk (if the value can be represented in Latin-1) or an iTXt chunk (which supports arbitrary Unicode strings). Installation ============ Note that this library **requires Flash 10 or higher**. Unfortunately, until Adobe decides what they're doing with the next version of Alchemy, this library won't work in any SWF compiled to target Flash player 11 (SWF version 13) or above (as of Flash Player 11.2). So, you can target Flash 10 (SWF versions 10-12) only for now. *Update:* It seems this library works fine even with recent versions of Flash Player (11.7 at the time of writing). Go figure. ### ActionScript 3 If you're using ActionScript 3 you can simply [download the SWC][swc] file and link it to your project. There are also ["slim" versions][slim] of the library that contain only a single compression method each; these are recommended for production since they are smaller (assuming you only use one compression level). To link an SWC into a project made with the Flash CS5.5 IDE, the steps are as follows: 1. In the File menu, select "ActionScript Settings...". 2. Under the "Library Path" tab, click the little red icon with the "f" logo on it. The tooltip of the button reads: "Browse to SWC file" 3. Browse to wherever it was that you saved the SWC, and select it 4. Press OK! To link an SWC in other versions of the Flash IDE, follow [this guide][how-to-swc] instead. ### HaXe If you're using haXe, just use the source directly instead of fiddling with SWCs (actually, your project won't compile if you use the SWC). All you need are the [PNGEncoder2.hx][PNGEncoder2.hx] and [DeflateStream.hx][DeflateStream.hx] files. Compiles under both haXe 2 and 3. If you want to have only one compression method compiled (to cut down on generated code size), add `-D FAST_ONLY`, `-D NORMAL_ONLY`, or `-D GOOD_ONLY` to your compile options (this is equivalent to using the slim SWC versions). The `decode` method is by default not compiled in; to enable it, add the `-D DECODER` compile option (which can be combined with the others above). [blog]: http://moodycamel.com/blog/2011/a-better-png-encoder-for-flash [haxe]: http://haxe.org/ [encoder]: https://github.com/mikechambers/as3corelib/blob/master/src/com/adobe/images/PNGEncoder.as [in-spirit]: http://blog.inspirit.ru/?p=378 [swc]: https://github.com/cameron314/PNGEncoder2/raw/master/PNGEncoder2.swc [how-to-swc]: http://www.myflashlab.com/2010/01/17/how-to-use-swc/ [slim]: https://github.com/cameron314/PNGEncoder2/tree/master/slim [PNGEncoder2.hx]: https://github.com/cameron314/PNGEncoder2/blob/master/PNGEncoder2.hx [DeflateStream.hx]: https://github.com/cameron314/PNGEncoder2/blob/master/DeflateStream.hx [dead-alchemy]: http://blogs.adobe.com/flashplayer/2011/09/updates-from-the-lab.html