I was trying to further reduce the filesize of a SWF file by optimizing the embedded PNG graphics (using ImageOptim tool). To my surprise, this didn't yield any effect, so I created two test Images:
Original (433883 bytes)
Optimized (273723 bytes)
When embedding either of these assets in a simple ActionScript project, the compiled SWF is ~274kb in size. Which raises the question: Does Flex optimize embedded PNG assets during compile-time? If yes, is there some documentation about the optimization going on?
It can't be because of the SWF compression alone, because zipping the images doesn't reduce filesize at all.
Here's the Code for completeness:
package
{
import flash.display.Sprite;
public class SizeTest extends Sprite
{
[Embed("/assets/original.png")]
private var ImageAsset:Class;
public function SizeTest(){
}
}
}
The answer is yes, the flex compiler does automatically compress data using one of the inbult algorithms (probably ZLIB) and transparently decompresses it on the other side (flash player) just before it gives you access to the uncompressed data.
I was embedding a ByteArray into an SWF, and although the bytes are huge outside (200 KB), when embedded into a SWF it turns into 30 KB, producing almost exactly the same results as manually compressing this using ByteArray.compress("zlib").
I then tried manually compressing PNG/JPEG bitmaps, and it turned out larger than embedding it plainly using the [Embed] tag (172 KB as a compressed ByteArray vs. 168 KB as an embedded image). Letting the Flex compiler handle embedded data compression is actually better than trying to do your own tricks on the ByteArray side.
Edit: To answer your question on PNG embedding, its hard to tell what's going on inside the flex compiler/flash player. Although known for proper documentation, Adobe is also known for many "undocumented features". Your specific question is best sent to a flash player architect (eg Tinic Uro) or an adobe evangelist (eg Lee Brimelow), some of whom you can easily reach on facebook (see this list).
The swf format has internally a special format for 32 bit PNGs (those with an alpha channel) where they get split up into a 24bit png and a greyscale alpha mask, whereby the alpha mask gets JPEG compressed. No totally sure if Flex Builder does that kind of optimization since I remember that at least in an older version embedded PNG where not at all optimized.
Nevertheless, if you are looking for a tool that can optimize embedded images in swfs you should check out Joa Ebert's "Reducer": http://blog.joa-ebert.com/2009/08/08/reducer/
Related
Today, I use FreeImage 3.15.4.0 to generate TIFF images. Some of my users tells me that he cannot read such images because its library (C++/QT I think) can't read them.
The images generated are readable with ImageJ and some other image processing tools.
So I wonder:
How to be sure that my image respect the standard (FreeImage rely on libtiff 4.0.3)?
Are my images too complex? (32 bits float images)
Does a simple standard format exist for 32 bits depth float images?
EDIT
I check by hand that my image followed the format described by adobe: http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf.
So, does exist a library comparative to know what part of specification is supported by which library?
Answer to 3 questions: yes.
The fact is QT, like others, is not able to display 32 bits float images: This is not supported by the QImage class (http://doc.qt.io/qt-5/qimage.html#Format-enum).
So the user will have to convert the image in something QT (the system in fact) is able to display.
i have seen almost all relevant threads on almost whole internet. and i m still confused..
i m working on a drawing app ( flex / air ),
1- where user loads image file,(bitmapdata > bitmap > movieclip base layer)
2- add layer ( new sprite > movieclip "second object in display list")
3- draw on this sprite ( graphics.draw circle / etc, lot of other details etc)
4- usr can add more layers etc, name layers etc ... all sprites are of same size as bitmap
Q1. now i wanted to save this main movieClip (part of UIComponent ) as swf file. so user can read again and continue work. almost like i do with photoshop.
comment: i know it sounds too generic, to ask such detailed thing. so please be patient..
i have been fiddling around with byteArray. and Air File Object, flash.net.fileReference etc...
Q2. (main question), i don't want to convert drawn sprites to bitmapdata and then do bytearray. ( in my mind) it will convert everything to pixels, which i don't want.
Q3. is there some auto magical line which will do everything..(save drawn vectors / shapes) in sprites as is?? (less chances). if i can read swf as movieClip, i can check sprites for layers and everything else... problem is writing this to disk as swf file.
please share your thoughts and feel free to guide,in all possible directions..
thanks in advance for your valuable time..
In an ideal world you would just write
YourByteArray.writeObject(YourCanvasSprite);
That doesn't work however since serialize only works with data that is readable and writeable (and public). So you need to make it possible to recreate the graphic. You might be able to simplify that by using IGraphics (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/IGraphicsData.html) as these should be possible to serialize. So if you subclass Sprite and store "drawing commands" and the parameters, and let the object have a restore function, it should be possible to save it to a byteArray. It's far from a one-liner though, but probably a little bit easier than making and reading SVG.
i'm thinking the cleanest solution to this problem would be to use SVG (maybe EPS). i'm unfamiliar with any library that will convert drawn vector objects into SVG, but since SVG is simply an XML file you could study the SVG architecture and create your own: W3C - Scalable Vector Graphics (SVG) 1.1 (Second Edition). the following open source project may help you write one and can also be used to read SVG into Flash: New Flex and Flash SVGWeb Components
a less clean, and perhaps more complicated way to solve this problem could be to write your own SWFs, as you mentioned. in order to do so you would have to generate .swf file at runtime, which you could accomplish by using NativeProcess to pass arguments (namely an ActionScript file containing your drawing information, child layers with names, etc.) to MXMLC from the Flex SDK.
i find both answers useful. and with time,i have realized that in both cases it might be more work than i can handle. meanwhile, i was testing other pixels bases approaches as well. so i finally took decision of going through pixel way. user can save layers as png files with transparency.
if some person (other readers) come to this post, i wanted to conclude quickly, i have found really valuable drawing library named "graffiti" for as3. it almost does 80% of things, which i was hoping to do. so i am using that and tweaking it for my needs. huge thanks and respect to all great ppl who replied from their valuable time..
I am having an AIR applicaiton which is supposed to uncompress the file of huge size (>1GB)
I tried commonly discussed utilities i.e. FZip nochump and few more
I face the same problem with all of them,
They tyr to unzip the entire file in the memory (using ByteArray.defalte method)
This works well with the files of small size howevre they just hang the applicaiton if the size of the file is big (>1GB)
Any suggestions?
Is there not a way you could use file spanning similar to the RAR formats. I think 7-Zip's 7Z supports it also. Depending on how to the decompression library is implemented, file spanning could reduce the memory usage theoretically.
Try looking into using the LZMA SDK a la 7-Zip:
http://www.7-zip.org/sdk.html
Maybe there's Flex bindings.
I agree with sammy, Air it's not the best solution for a task like that, IMHO it's better to include in your distribution a native utility to expand your files (remember that you need an utility for each platform that you want to support) then use the new Air2 API to invoke them. Doing this way the expansion of the archive is done in a separate process without freezing your app.
Maybe you can boundle just one utility if you are sure that every platform has a common runtime (ex. java).
I'm trying to use Adobe's OggVorbis library. But I can't seem to get the Sound object to loop.
I even tried looping the _sound object inside the AudioDecoder.as in the "com.automatastudios.audio.audiodecoder" package.
Do you really have to reload the file and stream it over and over?
If you're streaming, then yes you'll have to jump back the beginning of the stream. A stream, by definition, is a constant link to the server and does minimal loading of files locally.
But, if you're not really streaming, you should have no problem loading up a file and caching it locally then playing it over and over.
Since you mention Alchemy, there may be other unknown issues if you're trying to use a converted C library, as opposed to native ActionScript.
[Note; I didn't know the OggVorbis library for Flex before now].
I have a legacy file format that contains sounds embedded in it (in various encodings). I would like to be able to play these sounds in Flash (Air?) by reading the sound bytes out of the file and instantiating a Sound object with them.
If the sound is unencoded (e.g., raw pcm), I've found that I can use the new flex 4 SampleDataEvent.SAMPLE_DATA event to play the sound.
However, if the sound is encoded (e.g., mp3), then I'm at a loss. The sound expected by SampleDataEvent.SAMPLE_DATA has to be raw pcm. From what I've seen, encoded Sounds can only be instantiated by [Embed]ing them, or by using a URLRequest with Sound.load().
Surely there's a third way? AMF or e4x?
There are really only two routes for you to go. The first is to write a decoder in ActionScript. You may be able to use Alchemy to port over some C/C++ code to make this job significantly easier (and possibly more performant). This is exactly how I got Ogg Vorbis playback to work with Flash.
The other option is to dynamically create a valid SWF inside of a ByteArray. That SWF could contain an embedded sound object that was made up of your sound data. A number of folks have pulled off similar hacks in the past before Flash Player 10 was available. I believe you can find a good place to start in Andre Michelle's and Joa Ebert's PopForge codebase.