Sunday, May 31, 2009

Creating Zip files with Adobe AIR with the nochump library

Following up on my previous post, here's how to archive a bunch of files and make a zip file.

After getting all the files you want to put in the archive, create a new ZipEntry object for each file and add it to a ZipOutput object using the putNextEntry() of the ZipOutput class. Then pass the ByteArray data of the file to the write() method of the ZipOutput class and close the entry by using the closeEntry() method. Finally, call the finish() method once you have done the same for all the files.

Here's the code snippet :

import flash.events.FileListEvent;
import flash.filesystem.*;

import nochump.util.zip.*;

private var zipInput:File = new File();
private var zipOutput:File = new File();
private var zipFile:ZipOutput;

private var files:Array = new Array();

private function loadFiles():void
{
zipInput.browseForOpenMultiple("Open ZIP file");
zipInput.addEventListener(FileListEvent.SELECT_MULTIPLE, onSelect);
}

private function onSelect(e:FileListEvent):void
{
for(var i:uint = 0;i < e.files.length;i++)
{
var stream:FileStream = new FileStream();
var f:File = e.files[i] as File;
stream.open(f,FileMode.READ);
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData);
var file:Object = new Object();
file.name = f.name;
file.data = fileData;
files.push(file);
}
}

private function createZIP():void
{
zipFile = new ZipOutput();
for(var i:uint = 0; i < files.length; i++)
{
var zipEntry:ZipEntry = new ZipEntry(files[i].name);
zipFile.putNextEntry(zipEntry);
zipFile.write(files[i].data);
zipFile.closeEntry();
}
zipFile.finish();

zipOutput.browseForSave("Select target directory");
zipOutput.addEventListener(Event.SELECT, onSave);
}

private function onSave(e:Event):void
{
var archiveFile:File = e.target as File;
if(!archiveFile.exists)
{
var stream:FileStream = new FileStream();
stream.open(archiveFile,FileMode.WRITE);
stream.writeBytes(zipFile.byteArray);
stream.close();
}
}

As usual you can download the project archive here. Happy experimenting :D

Saturday, May 30, 2009

Extracting Zip files in Adobe AIR with the nochump library

Today, I'm going to show you how you can use the nochump library to extract zip files with Adobe AIR.

The ZipFile class constructor takes an IDataStream object as the parameter.Here you can use a ByteArray or a FileStream object which contains the data of the zip file. The entries property of the ZipFile object contains all the files in the archive as ZipEntry objects. Here the directory itself(excluding the files inside it) also counts as a ZipEntry object, so make sure to check using the isDirectory property of the ZipEntry object. Finally get the data of a single file using zipFile.getInput() method.

Here's the code :

import flash.filesystem.*;
import flash.net.FileFilter;

import nochump.util.zip.*;

private var zipInput:File = new File();
private var zipOutput:File = new File();
private var zipFile:ZipFile;

private function loadZIP():void
{
var filter:FileFilter = new FileFilter("ZIP","*.zip");
zipInput.browseForOpen("Open ZIP file",[filter]);
zipInput.addEventListener(Event.SELECT, onSelect);
}

private function onSelect(e:Event):void
{
var stream:FileStream = new FileStream();
stream.open(zipInput,FileMode.READ);

zipFile = new ZipFile(stream);
extract.enabled = true;
}

private function extractZIP():void
{
zipOutput.browseForDirectory("Select Directory for extract");
zipOutput.addEventListener(Event.SELECT, onDirSelect);
}

private function onDirSelect(e:Event):void
{
for(var i:uint = 0; i < zipFile.entries.length; i++)
{
var zipEntry:ZipEntry = zipFile.entries[i] as ZipEntry;
// The class considers the folder itself (without the contents) as a ZipEntry.
// So the code creates the subdirectories as expected.
if(!zipEntry.isDirectory())
{
var targetDir:File = e.target as File;
var entryFile:File = new File();
entryFile = targetDir.resolvePath(zipEntry.name);
var entry:FileStream = new FileStream();
entry.open(entryFile, FileMode.WRITE);
entry.writeBytes(zipFile.getInput(zipEntry));
entry.close();
}
}
}

You can download the project archive here. Happy experimenting :D

Wednesday, May 13, 2009

Introducing Simple3D - A library for 3D in Flash Player 10

Simple 3D is a library for developing 3D content in Flash Player 10.Unlike the other major 3D engines like Papervision3D, Away3D, Alternativa3D, Simple3D is just a library of standalone classes for 3D content.Using a standalone class greatly reduces compile size. The compile size of the SWF is around 3KB. Currently, the library contains 5 primitives and an ASE parser. I'm working on a couple more parsers and i'll release it soon.

Here is a simple sphere demo.




























Download : Simple3D Google Code Page

If you guys have any ideas to improve the code, or would like to contribute to the library, just drop a comment. I have created a Google Group for discussion.You can find it here.

Happy coding :D

Friday, May 8, 2009

Flash CS4 Tutorial : Using the drawTriangles method to render 3D objects

I’d like to say hello and welcome to those of you reading my feeds via MXNA. In this tutorial, we are going to use Flash Player 10’s 3D capabilities to render a cube. The drawTriangles method added to the Graphics class is used to render 3D objects in FP10. Lets get started.

First up,create a new document class. Here we’re going to name it Cube3D. Open the Cube3D.as file and type in the following code.

 

package    
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    public class Cube3D extends Sprite
    {
        private var matrix3D:Matrix3D;
        private var vertices:Vector.<Number>;
        private var projectedVertices:Vector.<Number>;
        private var UVData:Vector.<Number>;
        private var indices:Vector.<int>;
        private var cube:Sprite;

        public function Cube3D()
        {
            matrix3D = new Matrix3D();
            vertices = Vector.<Number>([50,-50,50,
                                         50,-50,-50,
                                        -50,-50,-50,
                                        -50,-50,50,
                                        50,50,50,
                                        50,50,-50,
                                        -50,50,-50,
                                        -50,50,50
                                        ]);
            projectedVertices = new Vector.<Number>;
            UVData = new Vector.<Number>;
            indices = Vector.<int>([3,1,0, 3,2,1, 5,7,4, 5,6,7, 1,4,0, 1,5,4, 2,5,1, 2,6,5, 3,6,2, 3,7,6, 7,0,4, 7,3,0]);

            cube = new Sprite();
            addChild(cube);

            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onEnterFrame(e:Event):void
        {
            cube.x = cube.y = 200;

            matrix3D.appendRotation(1,Vector3D.X_AXIS);
            matrix3D.appendRotation(1,Vector3D.Y_AXIS);
            matrix3D.appendRotation(1,Vector3D.Z_AXIS);           

            Utils3D.projectVectors(matrix3D,vertices,projectedVertices,UVData);

            cube.graphics.clear();
            cube.graphics.beginFill(0x0066FF);
            cube.graphics.lineStyle(1,0x0000FF,1);
            cube.graphics.drawTriangles(projectedVertices, indices);
            cube.graphics.endFill();
        }
    }
}

Now lets take a look at the code:

Now we can use the Vector class to store data instead of Arrays. Vectors are similar to arrays but allow you to store only one type of data. The vertices vector stores the xyz co-ordinates of the 8 vertices of the cube. In order to draw a 3D object, we use the drawTriangles method. The syntax for this method is

drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = “none”)

For the indices parameter, we have to split the cube into triangles. A good way for that is to take 1 side of a cube, and split it into 2 triangles. Read the drawTriangles section of this post by senocular for better understanding of splitting an object into triangles. A section from the post:

Square Triangles indices

As you can see, a square can be split up into 2 triangles.For the square, the indices are 0,1,2 and 1,2,3. Similarly using the same technique for the cube’s 6 sides, we can calculate the indices.

Look at the following code:

matrix3D.appendRotation(1,Vector3D.X_AXIS);

matrix3D.appendRotation(1,Vector3D.Y_AXIS);

matrix3D.appendRotation(1,Vector3D.Z_AXIS);

This is equivalent to rotating through the X,Y&Z axes by 1 degree. Hence this code is executed in every frame. Now take a look at the next line :

Utils3D.projectVectors(matrix3D,vertices,projectedVertices,UVData);

The syntax for the projectVectors method is projectVectors(m:Matrix3D, verts:Vector.<Number>, projectedVerts:Vector.<Number>, uvts:Vector.<Number>)

This method, using a projection Matrix3D object, projects a Vector of three-dimensional space coordinates ( verts ) to a Vector of two-dimensional space coordinates ( projectedVerts ). This method gives us the 2D vertices (projectedVertices) to use in the drawTriangles method.

Here is the final cube :



And with a little experimenting, here is a pyramid :




Feel free to drop a comment if you want to kknow anything.
Happy experimenting :D

FXG Tutorial : Understanding Paths

Continuing on the FXG Tutorials, in this tutorial, we will be seen Paths in FXG. Paths represent the outline of a shape in FXG. Paths are created using the Path element and the co-ordinates are given in its data attribute. A Path element supports fills,strokes,filters and blendmodes.



Path data contains numbers and specific letters which specify instructions (M indicates a moveto command, the L indicate lineto command, and the z indicates a closepath command).


Here is the example:



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="library://ns.adobe.com/flex/spark">

<fx:Library>

<fx:Definition name="Triangle">
<Group>
<Path data="M 100 100 L 50 200 L 150 200 z">
<fill>
<SolidColor color="#FF0000" />
</fill>
<stroke>
<SolidColorStroke weight="3" color="#0000FF" />
</stroke>
</Path>
</Group>
</fx:Definition>

<fx:Definition name="Square">
<Group>
<Path data="M 100 100 L 200 100 L 200 200 L 100 200 z">
<fill>
<SolidColor color="#FF0000" />
</fill>
<stroke>
<SolidColorStroke weight="3" color="#0000FF" />
</stroke>
</Path>
</Group>
</fx:Definition>

</fx:Library>

<Group>
<layout> <HorizontalLayout/> </layout>
<fx:Triangle/>
<fx:Square/>
</Group>

</Application>

As you can see, in the Path data of the Triangle,we have . This merely says : First, Move to 100,100. Then draw a Line to 50,200. Then draw a Line to 150,200. Then close the Path. We can use this to draw any shape that we want easily. You can read more here. Happy experimenting :D. Feel free to drop a comment about anything. Happy experimenting :D

FXG Tutorial : Creating and using Symbols

In the previous tutorial, I showed you how to create a simple Hello World tutorial in FXG. In this tutorial, we will be creating and using symbols. Symbols are nothing but a set of graphics with a defined name which can used to use it multiple times without having to rewrite the code.Here is the code:



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="library://ns.adobe.com/flex/spark">

<fx:Library>
<fx:Definition name="Square">
<Group>
<Rect width="200" height="200">
<fill>
<SolidColor color="#FF0000" />
</fill>
</Rect>
</Group>
</fx:Definition>

<fx:Definition name="Circle">
<Group>
<Ellipse width="200" height="200">
<fill>
<SolidColor color="#FF0000" />
</fill>
</Ellipse>
</Group>
</fx:Definition>

<fx:Definition name="SampleText">
<Group>
<SimpleText text="This is a sample text"/>
</Group>
</fx:Definition>
</fx:Library>

<Group>
<layout>
<VerticalLayout/>
</layout>

<fx:Square/>
<fx:Circle/>
<fx:SampleText/>
</Group>

</Application>


We can create symbols with the Definition tag. The definitions must be placed inside of the Library tag. As you can see, in the Definition tag, the name attribute is used to specify the name for the symbol. FXG also allows 2D transformations with the Matrix class. We can also apply Flex effects,filters,transitions,etc. in FXG.Happy Experimenting :D

FXG Tutorial : Getting Started with a Hello World Example.

FXG is an XML based graphics interchanged format for the Flash Platform. In this tutorial,we are going to get started with FXG with a simple Hello World example. So after you set up Flex Builder with the latest nightly build of Flex 4, (You can see how here if you don’t know.) we can start.

FXG documents have a logical structure. The Graphic element serves as the root for any FXG document. The Group elementis used to group related graphic elements.Currently, basic shapes such as Rectangle and Ellipse can provided but we can easily create our required shapes with the given functions.We can add text with the SimpleText tag which provides simple text formatting as well.

Here is the Hello World code:



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="library://ns.adobe.com/flex/spark">

<Graphic>
<Group>
<Rect width="200" height="200">
<fill>
<SolidColor color="#000000"/>
</fill>
<stroke>
<SolidColorStroke weight="3" color="#FF0000"/>
</stroke>
</Rect>
<SimpleText text="Hello World" x="50" y="50"/>
</Group>
</Graphic>

</Application>


This will create a black square with a red stroke with the text “Hello World”. I’ll be posting more tutorials on FXG soon. Happy experimenting :D

New IDE for Pixel Blender - Conduit

A company called Lacquer has just released the first 3rd party tool for creating Pixel Blender filters named Conduit. This application lets you to create Pixel Blender filters in a visual design environment using drag and drop manipulation, without the need to learn the Pixel Blender language. It exports a Pixel Blender bytecode (.pbj) file which can be used in Flash Player 10 as filters,fills,etc. As far as pricing is concerned

Conduit for Flash Pixel Bender is currently in beta testing. For a limited time, the product can be preordered for 50 euros (about 68 USD*).Preorders include download access to the latest beta versions for both Mac and Windows (please note that the Windows beta is not yet available but will be released in October 2008).

And for those who want a free edition, there is also Conduit Live Home which has a couple of limitations :

  • Only iSight (Apple web camera) is supported for video capture
  • Video record-to-disk is not available
  • Maximum image and video resolution that can be imported is 320*240 pixels
  • Export is not available

Currently, only the Mac version is available for download. The Windows version is expected to be available in October 2008.

Conduit Live Home can be downloaded at Conduit Live Home.

You can find intros and tutorials here.

ASDoc for MXML files

The Flex SDK page has a spec titled “ASDoc in MXML“.

Currently there is no way for users to add documentation to components defined in mxml files. The asdoc tool doesn’t read the comments in mxml files. Increasingly more components in the flex framework are being written in mxml.

Adding support for mxml in the asdoc tool would help developers to generate documentation for their components.

Several customer have also added requests in JIRA to support class level comments in mxml files.

So now you can add ASDoc comments by the syntax <!— asdoc comment –> . The — are necessary for the compiler to understand that they are ASDoc comments.

To get the full details chect out the spec : ASDoc in MXML.

AlivePDF Tutorial : How to create a PDF file with Flex/AIR

Here, we are going to see how to use the alivepdf library written by Thibault Imbert. This library allows us to create pdf content with Flex. In this tutorial, we will be using Adobe AIR in order to save the file. So lets get started. First create a new Flex project and select Desktop Application as the type. Download the AlivePDF library here. Copy the swc file and paste it in the libs folder. Now in the main application file, type the following code.


<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import org.alivepdf.pdf.PDF;
import org.alivepdf.saving.Method;
import org.alivepdf.fonts.*;
import org.alivepdf.pages.Page;
import org.alivepdf.display.Display;
import org.alivepdf.layout.*;

private var pdf:PDF;
private var file:File;
[Embed( source="/assets/o-png24.png", mimeType="application/octet-stream" )]
private var pngBytes:Class;
public function generate ():void
{
var pdf:PDF = new PDF( Orientation.PORTRAIT, Unit.MM, Size.A4 );
pdf.setDisplayMode( Display.FULL_PAGE, Layout.SINGLE_PAGE );
var newPage:Page = new Page ( Orientation.PORTRAIT, Unit.MM, Size.A4 );
pdf.addPage( newPage );
pdf.setFont(FontFamily.ARIAL , Style.NORMAL, 12);
pdf.addText("This is a sample text",5,15);
pdf.drawCircle(25,35,15);
pdf.addPage();
pdf.addImageStream( new pngBytes() as ByteArray );
var fs:FileStream = new FileStream();
file = File.desktopDirectory.resolvePath("testPage.pdf");
fs.open( file, FileMode.WRITE);
var bytes:ByteArray = pdf.save(Method.LOCAL);
fs.writeBytes(bytes);
fs.close();
}
]]>
</mx:Script>
<mx:Button click="generate()" label="Generate PDF" horizontalCenter="0" verticalCenter="0"/>
</mx:WindowedApplication>

and Run the application.

The main class here is PDF. The addPage method adds a new page. Similarly, there are a lot of options such as addImage, addText and also graphic methods such as drawCircle. drawRect,etc.You can look at the documentation for this given in the zip file.

Happy experimenting :D

Thursday, May 7, 2009

Dynamically changing Pixel Blender data at runtime

In my previous post, i had demonstrated the use of Pixel blender filters in Flex. In this post, we will be modifying the file that we did last time so that the user can change the red,blue and green channels and the alpha values at runtime.So if you haven’t done so , finish the previous tutorial. We can access the data of the Pixel Blender filter by the data property of the Shader class.The data property is an object of type ShaderData and it contains all the variables and parameters of the filter. The parameters are available as variables of type ShaderParameter. Here, we are going to use the same filter we used last time and we are going to allow the user to change the values of the color parameter at runtime with a Slider. Open the mxml file that you used for the previous tutorial and make the changes as :



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://ns.adobe.com/mxml/2009" xmlns:gumbo="library:adobe/flex/gumbo" xmlns:mx="library:adobe/flex/halo" applicationComplete="init()">
<Script>
<![CDATA[
import flash.display.*;
import flash.filters.ShaderFilter;
[Bindable]private var shader:Shader;
private var shaderFilter:ShaderFilter;
[Embed(source="assets/RGBAEdit.pbj", mimeType="application/octet-stream")]
private var ImgFilter:Class;

private function init():void
{
shader = new Shader(new ImgFilter());
shaderFilter = new ShaderFilter(shader);
img.filters = [shaderFilter];
}

private function apply(e:Event):void
{
shader.data.color.value[0] = rVal.value;
shader.data.color.value[1] = gVal.value;
shader.data.color.value[2] = bVal.value;
shader.data.color.value[3] = aVal.value;
shaderFilter = new ShaderFilter(shader);
img.filters = [shaderFilter];
}
]]>
</Script>

<mx:Panel id="panel" title="Pixel Blender Test"> <mx:Image id="img" source="@Embed('assets/test.png')"/>

<mx:HBox>

<mx:Label text="Red"/>

<mx:HSlider id="rVal" liveDragging="true" minimum="0" maximum="1" value="1" change="apply(event)"/>

<mx:Label text="Green"/>

<mx:HSlider id="gVal" liveDragging="true" minimum="0" maximum="1" value="1" change="apply(event)"/>

</mx:HBox>

<mx:HBox>

<mx:Label text="Blue"/>

<mx:HSlider id="bVal" liveDragging="true" minimum="0" maximum="1" value="0" change="apply(event)"/>

<mx:Label text="Alpha"/>

<mx:HSlider id="aVal" liveDragging="true" minimum="0" maximum="1" value="1" change="apply(event)"/>

</mx:HBox>

</mx:Panel>

</Application>

Pixel Blender Tutorial : Using Pixel Blender in Flex

Pixel Blender Toolkit is a new graphics programming language being developed by Adobe. Pixel Blender Toolkit can be used to create Pixel Blender filters and effects. You can find a lot of sample filters in the Gallery in Adobe Labs and in the Pixel Blender Exchange.  The Pixel Blender reference(which is in the docs folder inside your Pixel Blender Toolkit Folder with the name “PixelBenderLanguage10“) explains the basics of the language. Start the Adobe Pixel Blender Toolkit and click on “Create a new Filter” button. You’ll see that a small program is automatically generated. Type the following code and save it with any filename.

 
<languageVersion : 1.0;>

kernel RGBAEdit <
namespace : "My Filters";
vendor : "Pradeek";
version : 1;
description : "Editing RGBA values of an image";
>
{
input image4 image;
parameter float4 color
<
minValue:float4(0, 0, 0, 0);
maxValue:float4(1, 1, 1, 1);
defaultValue:float4(1, 1, 0, 1);
>;
output pixel4 result;

void evaluatePixel()
{
result = sampleNearest(image,outCoord());
result *= color;
}
}


Press Run. You will be prompted to load a image. Load it and run. You will see the image and the parameters on the side with which you can change the red,blue,green colors and the alpha of the image.Click File and “Export Kernel Filter for Flash Player“. This creates a Pixel Blender Byte Code file (.pbj file) which we can use in flex.



Now, create a Flex project and create a folder named assets inside the src folder and copy paste the .pbj file that you generated and a sample image into the assets folder. Now type in the following code in your mxml file. I have named the byte code file as RBGAEdit.pbj and the sample image file as test.png.




<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://ns.adobe.com/mxml/2009" xmlns:gumbo="library:adobe/flex/gumbo" xmlns:mx="library:adobe/flex/halo" applicationComplete="init()">

<Script>
<![CDATA[

import flash.display.*;
import flash.filters.ShaderFilter;

private var shader:Shader;
private var shaderFilter:ShaderFilter;

[Embed(source="assets/RGBAEdit.pbj", mimeType="application/octet-stream")]
private var ImgFilter:Class;

private function init():void
{
shader = new Shader(new ImgFilter());
shaderFilter = new ShaderFilter(shader);
img.filters = [shaderFilter];
}

]]>
</Script>

<mx:Image id="img" source="@Embed('assets/test.png')"/>

</Application>


This is just a basic usage of the Pixel Blender Toolkit. You can use it as



  • a filter (ShaderFilter)

  • a blend mode

  • a fill and

  • a number cruncher



Happy experimenting :D

Hello World Application in Gumbo

I thought I should follow up on my previous post with a very simple Hello World application.

Here is the code:



<Application xmlns="http://ns.adobe.com/mxml/2009">
<Button label="Hello World">
</Button>
</Application>

Thats it. As you can see there is no more <mx:…> stuff. Just plain <Button/>. There aren’t many Gumbo components ,so this is just the beginning. I’ll put up more stuff once I make them.

Gumbo!!! Setup Flex 4 in Flex Builder 3

So I finally decided to jump into Flex 4 (codenamed “Gumbo”).Gumbo has a lot of changes from Flex 3. Check out this article for what’s new in Flex 4 . Gumbo doesn’t have a stable release yet so download a nightly build. Gumbo needs Flash Player 10, so you have to download that as well. So lets get started.

First download and install Flash Player 10 (Astro).

Follow the instructions on the page. Next, download the latest nightly build of Gumbo here and extract

it to a folder in your computer. Start Flex Builder and select Window -> Preferences . Choose “Installed Flex SDKs” in the Flex category and click the Add button. Browse and select the folder where you unzipped the SDK and click OK to add the SDK. Select the checkbox near Flex 4 to make it the default SDK if you want to.

Creating a Flex 4 Project:

Create a new project as you normally would. Right click the project, select Properties and select “Flex Compiler”. Under the HTML Wrapper, change the “Require Flash Player version” as 10.0.0. If you did not set Flex 4 SDK as the default SDK, then change the Flex SDK version to Flex 4 using the combo box and click OK.

Congrats! ,You have set-up your first Flex4 project in Flex Builder 3.

I’ll put up code samples and sample apps. Feel free to drop a comment if you found this useful.

Hello world!

Hey guys. This is my personal blog on my random experiments . Feel free to drop comments.