Flash, ZLib, and .NET
A week or so ago, I resumed work on our .NET based Flash file format library (the C++ version, known as SWFSource is generally considered to be the best lib for Flash encoding and is used in a ton of 3rd party SWF tools). The library should be available within the next few months so that you can begin construction of your own .NET enabled version of Flex or Laszlo (if you want to beta so that you can get started on it today, send me an email and I will get something out to you).
Images inside of Flash files can be stored in any of 5 formats. 3 of these formats use JPEG compression, and 2 of them use “Lossless” compression, which is simply ZLib compressed raw image data. So, we had to find a way to encode ZLib data. A few google searches suggested that the SharpZipLib from ICSharpCode could do this. However, at first glance this didn't appear to be accurate. There are a few namespaces, which all line up with file formats such as “Zip”, “GZip”, etc., however, no ZLib (contrary to popular belief, GZip is not simply Zlib compressed data). It took a little more digging to find, but ZLib support is definately there, hidden in the Zip.Compression.Streams namespace as a “DeflaterOutputStream.” Quite an interesting location to store this stuff (I would definately not have put it deep within the namespace used for working with Zip files), but, it is there nonetheless. Output ZLib compressed data, once you know where to find the objects, is pretty simple: just wrap a DeflaterOutputStream object around your output stream and go.
Now that we have our ZLib compression implemented, we can create a SWF with an embedded image fill applied to a shape like so:
BitStreamWriter writer = new BitStreamWriter(s);
writer.Write(new SwfHeader(5, fileLength, new Rectangle(0,0, 10000, 10000), 15, 5));
writer.Write(new SetBackgroundColor(Color.FromArgb(0,255,0)));
DefineBitsLossless bitmapFill;
using(Bitmap b = (Bitmap)Bitmap.FromFile(imageFilename))
{
bitmapFill = new DefineBitsLossless();
bitmapFill.Data = LosslessBitmapData.FromBitmap(b,100);
bitmapFill.CharacterID = 2;
}
writer.Write(bitmapFill);
DefineShape ds = new DefineShape();
ds.Shape = new ShapeWithStyle();
ds.CharacterID = 1;
FillStyle fill = new BitmapFillStyle(bitmapFill);
ds.Shape.FillStyles.Add(fill);
ds.Shape.Records.Add(new ShapeRecordChange(new Point(0,0), fill));
ds.Shape.Records.Add(new ShapeRecordStraight(new Size(0,2000)));
ds.Shape.Records.Add(new ShapeRecordStraight(new Size(2000,0)));
ds.Shape.Records.Add(new ShapeRecordStraight(new Size(0,-2000)));
ds.Shape.Records.Add(new ShapeRecordStraight(new Size(-2000,0)));
writer.Write(ds);
writer.Write(new PlaceObject(1,20));
writer.Write(new ShowFrame());
writer.Write(new End());
writer.Flush();