LogoLogo
  • Home
  • Projects
  • About
  • Contact

Saving Files Directly from Flash Player 10

Devon O. · May 23, 2008 · Actionscript · 1 comments
3

So, while surfing around checking out the new Flash 10 features I ran across this intriguing quote over at ByteArray.org:

File Reference runtime access — Bring users into the experience by letting them load files into your RIA. You can work with the content at runtime and even save it back when you are done through the browse dialog box. Files can be accessed as a byteArray or text using a convenient API in ActionScript without round-tripping to the server. You no longer have to know a server language or have access to a server to load or save files at runtime.

Needless to say, I had to investigate this further. Sho ’nuff, if you check out the documentation for the FileReference object you’ll see a new save() method which accepts all manner of objects for its first argument (the second argument is just a string for the default file name). It so happens, if the first object is a ByteArray, it will simply write the instance, as is, straight to the users hard drive. Freaking amazing. What does this mean? Well, first off a lot less coding for the developer (no server side script to deal with). In addition, as the quote above points out, it means fewer trips to the server and fewer trips to the server means less bandwidth and less bandwidth means happier clients.

To give this a try I went back to my simple drawing application from a few posts ago and this time I enabled the “save” feature. Clicking the save button will turn your work of art into a ByteArray via the JPGEncoder class from the Adobe as3corelib package and the FileReference instance will deliver it straight to your desktop. No muss no fuss.

All this with only a simple little script like this:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package {  
 
    import com.adobe.images.JPGEncoder;
    import com.onebyonedesign.drawing.DrawingTablet;
    import com.onebyonedesign.drawing.events.DrawingEvent;
    import com.onebyonedesign.ui.events.ValueSliderEvent;
    import com.onebyonedesign.ui.OBO_ValueSlider;
    import flash.display.Sprite;
    import flash.net.FileReference;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFieldType;
    import flash.text.TextFormat;
    import flash.utils.ByteArray;  
 
    /**
    * Use FileReference instance to save image data directly from Flash to user's computer!
    * @author Devon O.
    */  
 
    [SWF(width="500", height="500", backgroundColor="#FFFFFF", framerate="31")]
    public class SaveImage extends Sprite {  
 
        private var _fr:FileReference;
        private var _imageBytes:ByteArray;
        private var _fmt:TextFormat = new TextFormat("_sans", 11);
        private var _titleText:TextField;
        private var _qualityText:TextField;
        private var _qualitySlider:OBO_ValueSlider;  
 
        public function SaveImage():void {
            _fr = new FileReference();  
 
            var tablet:DrawingTablet = new DrawingTablet(400, 400, 0xF4EBB9);
            tablet.x = 50;
            tablet.addEventListener(DrawingEvent.SAVE, onSave);
            addChild(tablet);  
 
            // Some user input stuff to determine file name and quality  
 
            var titleLabel:TextField = new TextField();
            titleLabel.defaultTextFormat = _fmt;
            titleLabel.selectable = false;
            titleLabel.mouseEnabled = false;
            titleLabel.autoSize = TextFieldAutoSize.LEFT;
            titleLabel.x = 50;
            titleLabel.y = 410;
            titleLabel.text = "File Name:";
            addChild(titleLabel);  
 
            _titleText = new TextField();
            _titleText.defaultTextFormat = _fmt;
            _titleText.type = TextFieldType.INPUT;
            _titleText.border = true;
            _titleText.maxChars = 23;
            _titleText.restrict = "A-Z_a-z0-9";
            _titleText.width = 150;
            _titleText.height = 17;
            _titleText.x = Math.round(titleLabel.textWidth + 55);
            _titleText.y = 410;
            addChild(_titleText);  
 
            var qualityLabel:TextField = new TextField();
            qualityLabel.defaultTextFormat = _fmt;
            qualityLabel.selectable = false;
            qualityLabel.mouseEnabled = false;
            qualityLabel.autoSize = TextFieldAutoSize.LEFT;
            qualityLabel.x = 270;
            qualityLabel.y = 410;
            qualityLabel.text = "Image Quality:";
            addChild(qualityLabel);  
 
            _qualitySlider = new OBO_ValueSlider(50, 1, 100, 50);
            _qualitySlider.x = Math.round(qualityLabel.x + qualityLabel.textWidth + 10);
            _qualitySlider.y = 416;
            _qualitySlider.addEventListener(ValueSliderEvent.DRAG, qualityHandler);
            addChild(_qualitySlider);  
 
            _qualityText = new TextField();
            _qualityText.defaultTextFormat = _fmt;
            _qualityText.border = true;
            _qualityText.selectable = false;
            _qualityText.mouseEnabled = false;
            _qualityText.width = 40;
            _qualityText.height = 17;
            _qualityText.x = Math.round(_qualitySlider.x + _qualitySlider.width + 10);
            _qualityText.y = 410;
            _qualityText.text = "50";
            addChild(_qualityText);
        }  
 
        private function qualityHandler(event:ValueSliderEvent):void {
            _qualityText.text = Math.round(event.value).toString();
        }  
 
        private function onSave(e:DrawingEvent):void {
            var encoder:JPGEncoder = new JPGEncoder(Number(_qualityText.text));
            _imageBytes = encoder.encode(e.image);
            _fr.save(_imageBytes, (_titleText.text || "my_drawing") + ".jpg");
        }
    }
}

It’s just that easy. But don’t tell anyone. Make them think you work hard for your money.

You know, back when Adobe aquired Flash, I was very worried they would concentrate mainly on it’s design ability and let the development aspect fall by the wayside (you ever try writing expressions in After Effects? In a word, it sucks). I was 100% wrong about that though. The Flash platform (Flash, Flex, and AIR) have become mindbendingly impressive in both design and development sides. Thank you, Adobe. Thank you, Astro.

Of course, again, you’ll need the Flash 10 plugin to view the example below:

Oh, and here's a quickie bonus 3d cube example - script only, you'll have to compile yourself:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package {  
 
    import flash.display.Sprite;
    import flash.events.Event;  
 
    [SWF(width="500", height="400", backgroundColor="#FFFFFF", framerate="31")]
    public class CubeExample extends Sprite {  
 
        private static const CUBE_SIZE:int = 150;  
 
        private var cube:Sprite;  
 
        public function CubeExample():void {
            initCube();
            addEventListener(Event.ENTER_FRAME, frameHandler);
        }  
 
        private function initCube():void {
            cube = new Sprite();  
 
            var s1:Sprite = createSide();
            var s2:Sprite = createSide();
            var s3:Sprite = createSide();
            var s4:Sprite = createSide();
            var s5:Sprite = createSide();
            var s6:Sprite = createSide();  
 
            s1.z = CUBE_SIZE * .5;
            s2.z = -CUBE_SIZE * .5;
            s3.rotationY = 90;
            s3.x = CUBE_SIZE * .5;
            s4.rotationY = 90;
            s4.x = -CUBE_SIZE * .5;
            s5.rotationX = 90;
            s5.y = CUBE_SIZE * .5;
            s6.rotationX = 90;
            s6.y = -CUBE_SIZE * .5;  
 
            cube.addChild(s1);
            cube.addChild(s2);
            cube.addChild(s3);
            cube.addChild(s4);
            cube.addChild(s5);
            cube.addChild(s6);  
 
            cube.x = 250;
            cube.y = 200;  
 
            addChild(cube);
        }  
 
        private function createSide():Sprite {
            var s:Sprite = new Sprite();
            s.graphics.lineStyle(2, 0x000000);
            s.graphics.beginFill(Math.random() * 0xFFFFFF, .15);
            s.graphics.drawRect( -CUBE_SIZE * .5, -CUBE_SIZE * .5, CUBE_SIZE, CUBE_SIZE);
            s.graphics.endFill();
            return s;
        }  
 
        private function frameHandler(event:Event):void {
            cube.rotationY += 5;
            cube.rotationX += 2;
        }
    }
}
  Facebook   Pinterest   Twitter   Google+
  • Custom Post Processing with the LWRP
    September 15, 2019 · 1 comments
    About a week ago, someone posted a comment on <a
    5424
    9
    Read more
  • FITC in Quick Review
    February 24, 2010 · 0 comments
    2104
    2
    Read more
  • Rockin and Rollin with the JiglibFlash Terrain
    March 16, 2010 · 8 comments
    2493
    6
    Read more
1 Comments:

Sorry, the comment form is closed at this time.

Devon O. Wolfgang

AIR | Unity3D | AR/VR

Unity Certified Developer

Technical Reviewer of “The Essential Guide to Flash CS4 AIR Development” and “Starling Game Development Essentials”

Reviewer of “The Starling Handbook”

Unity Engineer at Touch Press.

Categories
  • Actionscript (95)
  • AIR (16)
  • Flash (99)
  • Games (7)
  • Liberty (13)
  • Life (53)
  • Shaders (20)
  • Unity3D (21)
Recent Comments
  • MainDepth on Unity Ripple or Shock Wave Effect
  • Devon O. on Unity Ripple or Shock Wave Effect
  • Feral_Pug on Unity Ripple or Shock Wave Effect
  • bavvireal on Unity3D Endless Runner Part I – Curved Worlds
  • Danielius Vargonas on Custom Post Processing with the LWRP
Archives
  • December 2020 (1)
  • December 2019 (1)
  • September 2019 (1)
  • February 2019 (2)
  • December 2018 (1)
  • July 2018 (1)
  • June 2018 (1)
  • May 2018 (2)
  • January 2018 (1)
  • December 2017 (2)
  • October 2017 (1)
  • September 2017 (2)
  • January 2017 (1)
  • July 2016 (1)
  • December 2015 (2)
  • March 2015 (1)
  • September 2014 (1)
  • January 2014 (1)
  • August 2013 (1)
  • July 2013 (1)
  • May 2013 (1)
  • March 2013 (2)
  • December 2012 (1)
  • November 2012 (1)
  • September 2012 (3)
  • June 2012 (2)
  • May 2012 (1)
  • April 2012 (1)
  • December 2011 (2)
  • October 2011 (3)
  • September 2011 (1)
  • August 2011 (1)
  • July 2011 (1)
  • May 2011 (2)
  • April 2011 (2)
  • March 2011 (1)
  • February 2011 (1)
  • January 2011 (2)
  • December 2010 (3)
  • October 2010 (5)
  • September 2010 (1)
  • July 2010 (2)
  • May 2010 (5)
  • April 2010 (2)
  • March 2010 (7)
  • February 2010 (5)
  • January 2010 (5)
  • December 2009 (3)
  • November 2009 (1)
  • October 2009 (5)
  • September 2009 (5)
  • August 2009 (1)
  • July 2009 (1)
  • June 2009 (2)
  • May 2009 (6)
  • April 2009 (4)
  • March 2009 (2)
  • February 2009 (4)
  • January 2009 (1)
  • December 2008 (5)
  • November 2008 (2)
  • September 2008 (1)
  • August 2008 (6)
  • July 2008 (6)
  • June 2008 (9)
  • May 2008 (4)
  • April 2008 (3)
  • March 2008 (4)
  • February 2008 (9)
  • January 2008 (7)
  • December 2007 (6)
Copyright © 2021 Devon O. Wolfgang