Saving customized movieclip as an image to local disk (diy generator) - actionscript-3

dropbox.com/s/77euop1luqjreos/FINAL.fla
Ok i just gave up with this already. I cant think of any way to save the image created by a user. Its hard to explain but please check out the fla file of my work. Basically its a diy generator. The only thing missing is a save function. Ive read filereference but its always in a document class. My code is in the timeline. Please help I'm really stuck.
edit: I got a download button that is working now!! But it only saves a small part of the movieclip: Imgur

In order to create images, you need to access the pixel data of the MovieClip object. The data can be obtained by rendering a MovieClip into a BitmapData object and using this data, you can write your own encoder to convert it to any image format you’d like. Writing such encoder is not a trivial task and requires understanding of the image format algorithm, or you can use pre-written libraries. You can download the PNGEncoder and JPGEncoder , which is part of as3corelib, an open source project library.
Using the JPGEncoder, we can convert DisplayObject into ByteArray, suitable for saving into file. If using the JPGEncoder, it’ll look like this:
import com.adobe.images.JPGEncoder;
var jpgEncoder:JPGEncoder = new JPGEncoder(quality);
//remember bitmapData here is just an example (do not try to compile this code without declare this particular variable)
var byteArray:ByteArray = jpgEncoder.encode(bitmapData);
With the PNGEncoder, it’ll look like this:
import com.adobe.images.PNGEncoder;
//remember bitmapData here is just an example (do not try to compile this code without declare this particular variable)
var byteArray:ByteArray = PNGEncoder.encode(bitmapData);
Saving Into User’s Hard Drive
Using the FileReference.save() function, we can prompt the user to save the file with the following call.
var fileReference:FileReference=new FileReference();
//in case of JPGEncoder
fileReference.save(byteArray, ".jpg");
With the two combined, here’s an example how to use:
//remember to import
import flash.net.FileReference;
import com.adobe.images.JPGEncoder; //or import com.adobe.images.PNGEncoder;
import flash.utils.ByteArray;
import flash.display.BitmapData;
//where mc_canvas will be your MovieClip instance name
var bitmapData:BitmapData = new BitmapData(mc_canvas.width, mc_canvas.height);
bitmapData.draw(mc_canvas);
var jpgEncoder:JPGEncoder = new JPGEncoder(quality_slider.value);
var byteArray:ByteArray = jpgEncoder.encode(bitmapData);
//if you want to use PNGEncoder
//var byteArray:ByteArray = PNGEncoder.encode(bitmapData);
var fileReference:FileReference = new FileReference();
fileReference.save(byteArray, ".jpg");

Related

AS3 HMAC SHA-256 for Adobe AIR (desktop)

in Actionscript 3 i need to compute data (a string, utf-8), using a secret key (a string, utf-8).
This is the data (string) "symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559"
This is the secret key (string) "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
This is the result it must come out (string) "c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71"
Can someone solve this? (the result is correct, but i don't know the code to arrive at the result).
This is what i have tried so far:
// THE DATA
var dataToEncode:String = "symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559";
var byteArrayOfDataToEncode:ByteArray = new ByteArray();
byteArrayOfDataToEncode.writeUTF(dataToEncode); // we write the string into the ByteArray
// THE SECRET KEY
var secretKey:String = "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j";
var byteArrayOfSecretKey:ByteArray = new ByteArray();
byteArrayOfSecretKey.writeUTF(secretKey); // we write the secret key into the ByteArray
// WE COMPUTE THE SIGNATURE
var HMAC_SHA256:HMAC = new HMAC(new SHA256());
var byteArrayOfResultSignature:ByteArray = HMAC_SHA256.compute(byteArrayOfSecretKey, byteArrayOfDataToEncode);
var resultSignature:String = byteArrayOfResultSignature.readUTF();
// WE SHOW THE RESULT SIGNATURE
trace("The result signature is: "+resultSignature);
This HMAC class is created using this library (AS3Crypto):
https://github.com/Atmosphere/ActionScript/blob/master/src/com/hurlant/crypto/hash/HMAC.as
I found, thanks to the commentors, the asnwer to this.
The solution is com.adobe.crypto .
There is a class in the As3corelib (that you can download here
https://code.google.com/archive/p/as3corelib/downloads). You have to import those folders by going to "File-> Actionscript settings", and the click on the source path and then add the "com" folder there.
You will also need to download the Adobe Flex SDK (because some classes in As3corelib use some utility classes in the Flex SDK), unzip it, and then include the framework.swc file (search in the folders of adobe flex, it is in the frameworks/libs folder), going to "File-> Actionscript settings", and the click on the library path and then add the framework.swf there.
Now you are ready to do it, like this:
import com.adobe.crypto.*; // import this, to have access to the classes we need.
// then this code where you need it
var message:String = "symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559";
var secretKey:String = "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j";
var signature:String = HMAC.hash(secretKey, message, SHA256) ;
trace("The signature is: "+signature);
Hope it helps, have a beautiful day!

button to save as the video in the desktop

I use Adobe Flash Professional CS6 + as3 and I have a button to download or save as the video in the desktop but does not execute it? Why ? Where is the mistake?
import fl.video.FLVPlayback;
import flash.display.StageAlign;
import flash.events.Event;
import flash.display.MovieClip;
import flash.display.StageScaleMode;
import flash.media.SoundMixer;
myVideoPlayer.source = "";
addChild (myVideoPlayer);
function loadMyVideo (url:String):void
{
myVideoPlayer.source = url;
myVideoPlayer.visible = true;
}
videosaveas.addEventListener (MouseEvent.CLICK, videosaveas2);
function videosaveas2 (e:Event):void
{
file = new FileReference();
var fileReference:FileReference=new FileReference();
file.save (ByteData, "video.mp4");
}
I don't know if you know the difference between a Flash Player app and an AIR one but I'll put an example for an offline Flash Player app to download a file which is in the same directory as the SWF.
To load the file, I'll use an URLLoader object and then save it using a FileReference one.
Here, don't forget that FileReference.save() is allowed only after a user action (like a mouse click or keypress).
For the example, I'll use the same button for both operations (the user should press the button twice to get the saving file dialog).
var url_loader:URLLoader;
// at the first, we use the button to load the file
btn_download.addEventListener(MouseEvent.CLICK, load_the_file);
function load_the_file(e:MouseEvent): void {
url_loader = new URLLoader();
url_loader.dataFormat = URLLoaderDataFormat.BINARY;
url_loader.addEventListener(Event.COMPLETE, function(e:Event){
btn_download.removeEventListener(MouseEvent.CLICK, load_the_file);
// then we use the same button to download the file
btn_download.addEventListener(MouseEvent.CLICK, download_the_file);
})
url_loader.load(new URLRequest('file_path.ext'));
}
function download_the_file(e:MouseEvent): void {
var file_reference:FileReference = new FileReference()
file_reference.save(url_loader.data, 'default_file_name.ext');
btn_download.removeEventListener(MouseEvent.CLICK, download_the_file);
}
Here, using one button is just an example so you can, for example, show a loading message, use another way to load the file, use two buttons, ...
Then for an online app (a web app), you can use, for example, FileReference.download() :
var file_ref:FileReference = new FileReference();
file_ref.download(new URLRequest('http://www.example.com/file_path.ext'));
For AIR, you have a lot of possibilities using the File, FileStream and the FileReference classes, and you have a lot of example on the net ...
Hope that can help.

StageWebView in an AS3-Script

I allreday read a lot of helpful stuff in that forum. Now it's my first time I ask for specific help.
I'm pretty new to Flash and have a problem I struggle for more then a week now. The most efficient and elegant way for my problem is to put a StageWebView-Call into an as-File.
That would be the plan:
In my flash-File: Show a PDF document "xyz" and put it on the stage.
I alreday tried it with Switch-Case - But then I have trouble to get rid of the PDF's.
That was my Idea:
First the new as-File...
package {
import flash.display.MovieClip;
import flash.media.StageWebView;
import flash.geom.Rectangle;
import flash.filesystem.File;
import flash.display.Sprite;
import flash.display.Stage;
public class mypdf {
public var MyWebView:StageWebView
public var file:String
public var pdf:File
public function mypdf(ActFile:String) {
MyWebView = new StageWebView();
file = ActualFile; //MARKING #1
pdf = File.applicationDirectory.resolvePath(file);
MyWebView.stage = stage; //MARKING #2
MyWebView.viewPort = new Rectangle (200, 200, 400, 400);
MyWebView.loadURL(pdf.nativePath);
}
}
}
Than I want to call that in my flash-File...
stop();
var mynewpdf:mypdf = new mypdf("test.pdf");
Two erros are shown:
1120: Access of undefined property error ActualFile (at Marking #1)
1120: Access of undefined property error Stage (at Marking #2)
With a lot more work I could avoid the first error by defining a lot of different as-Scripts for each pdf.
My main problem is the second error.
It would be really nice if someone had any good ideas.
Bye,
Stephan
The second error means that you need to pass the stage to the web view. Either pass it to mypdf class as parameter, or make mypdf DisplayObject (extend Sprite for example) and add it to stage.
I'm not sure this will solve your issue anyways - I think StageWebView can simply display html. The PDF is displayed in your browser because an external plugin for that is launched.
In AIR the situation seems different: http://sujitreddyg.wordpress.com/2008/01/04/rendering-pdf-content-in-adobe-air-application/
StageWebView is wont support for nativePath, instead of using this, you can try with pdf.url. And StageWebView also having support for open .pdf files.
public function mypdf(ActFile:String) {
MyWebView = new StageWebView();
file = ActualFile; //MARKING #1
pdf = File.applicationDirectory.resolvePath(file);
MyWebView.stage = stage; //MARKING #2
MyWebView.viewPort = new Rectangle (200, 200, 400, 400);
addChild( MyWebView );
MyWebView.loadURL(pdf.url);
}
Because, StageWebView will support file:/// format, but in nativePath we got C://.., so, this will help you. Or
Simply convert your StageWebView to Display object, and then added it to your container by using addElement().
You can convert it by,
var _view:SpriteVisualElement = new SpriteVisualElement();
_view.addChild( MyWebView);
this.addElement( view );
To test by, simply call this method in added_to_stage method to test if stage is having or not. This error will come if stage is not setted means also.

embedding a font in a swf using as3

I have a project using flash (and AIR for android and eventuall iOS) for translating some phrases. Although most fonts are fine there are some that I have to load after the user has chosen the languages. Over a year ago I generated a couple of swf files (Bengali and Urdu) and put them on my web server. The flash application then loads them when required and everything is OK...
However as I am nearing implementing the project I thought I should generate the swf files for the other languages that are in the pipeline and for some reason I can't manage it! Needless to say I have misplaced (tidied) the original AS3 source for the two fonts I have done.
package
{
import flash.display.Sprite;
import flash.events.Event;
public class ArabicF extends Sprite
{
[Embed(source = "trado.ttf",
fontName = "ArabicX",
fontFamily = "ArabicY",
fontWeight = "normal",
fontStyle = "normal",
mimeType = "application/x-font",
advancedAntiAliasing="true",
embedAsCFF="true")]
public static const ArabicZ:Class;
}
}
This has expanded from a much simpler form as I added things to get it to work and I must have tried all permutations of true and false. I load the swf ok but then can't extract the class. With the two fonts I embedded before the swf class and the parameter all have the same name and they work fine (i.e.
Urdu.swf
then later:
var FontClass:Class = evt.target.applicationDomain.getDefinition("Urdu") as Class;
and then
Font.registerFont(FontClass.Urdu);
in the calling .as application with the above Arabic.swf I try
trace("1 Arabic "+evt.target.applicationDomain.hasDefinition("ArabicF"));
trace("2 Arabic "+evt.target.applicationDomain.hasDefinition("Arabic"));
trace("3 ArabicX "+evt.target.applicationDomain.hasDefinition("ArabicX"));
trace("4 ArabicY "+evt.target.applicationDomain.hasDefinition("ArabicY"));
trace("5 ArabicZ "+evt.target.applicationDomain.hasDefinition("ArabicZ"));
but all return false
PS also tried generating the Arabic.swf using fontswf.bat which again seems to make a very similar swf file which is loaded but I can't extract the class from it
PPS I'm using flashdevelop and the font swf are set up as AS3 standard project compiler options.
I don't use Flash Develop, but perhaps I can offer some perspective from my implementation.
If I wanted to embed Arial, the embedding swf would "Export for ActionScript" the embedded font. In its document class, use registerFont() as below:
Font.registerFont(Arial);
Like every other swf, you'd use a Loader to import it into your runtime, and at that point, the font will be available to your global table. You can query the complete list of registered fonts using enumerateFonts().
var fontList:Array = Font.enumerateFonts();
for (var i:int = 0; i < fontList.length; i++) {
trace(fontList[i].fontName);
}
Assuming we've got a TextField called "txt", you can then implement that font with setTextFormat() like so:
var format:TextFormat = new TextFormat();
format.font = "Arial";
txt.embedFonts = true;
txt.antiAliasType = AntiAliasType.ADVANCED;
txt.setTextFormat(format);
txt.defaultTextFormat = format;
A disclaimer from Adobe on the use of these last two settings:
"When you apply a TextFormat object to a text field using the
TextField.defaultTextFormat property or the TextField.setTextFormat()
method, only its defined properties are applied. Use the
TextField.defaultTextFormat property to apply formatting BEFORE you
add text to the TextField, and the setTextFormat() method to add
formatting AFTER you add text to the TextField."
As I said before, my workflow doesn't utilize Flash Develop, but rather Flash IDE to embed the fonts into the swfs. Your results may vary, but be aware you must set embedFonts to true, or it won't respond to your embedded font. I've lost hair on that issue before.
Hope that helps. Cheers,
OK In case someone else runs into similar problems this is stage one of the answer (really the answer to my original question) still have to sort out how to get the font to be used in the flash.font.engine apparatus!
The critical parts are:
Point #1. the embedded font swf must have a name that doesn't clash with ANY name registered in the calling script. Bizzare and (as far as I could search) undocumented. i.e. I have a list of languages uploaded via xml services to an xml object and that includes for instance 'English' however the font loading doesn't work until I make the loadable font file into 'EnglishF.swf' The obvious choice of just 'English.swf' fails. So my embedded font source is now called EnglishF.swf and reads:
package
{
import flash.display.Sprite;
import flash.text.Font;
import flash.system.Security;
Security.allowDomain("*");
/**
* ...
* #author patrick
*/
public class EnglishF extends Sprite
{
[Embed(source = "Kingthings Exeter.ttf",
fontName = "EnglishF",
fontFamily = "EnglishF",
fontWeight = "normal",
fontStyle = "normal",
mimeType = "application/x-font",
advancedAntiAliasing="true",
embedAsCFF="true")]
public static var myFont:Class;
}
}
and the using script goes:
private function fontLoaded(evt:Event):void {
var FontClass:Class
if (evt.target.applicationDomain.hasDefinition(font1Name)) FontClass = evt.target.applicationDomain.getDefinition(font1Name) as Class;
else if (evt.target.applicationDomain.hasDefinition(font2Name)) FontClass = evt.target.applicationDomain.getDefinition(font2Name) as Class;
try {
Font.registerFont(FontClass.myFont);
trace("successfully loaded " + FontClass);
} catch (err:Error) {
trace("couldn't register font "+FontClass.myFont+" =>"+err);
}
}
The line in the embedded script about security is because of point #2: the registerFont doesn't work across domains. In fact the Security.allowDomain() didn't work and to debug this I have had to copy/paste the swf files on the PC and change the loader.load(URLRequest()) accordingly
There is still an issue that although the font is registered and claims to be compatible with the flash.text.engine TextElement requirements it still fails to be used as in:
_tl = new Array();
var block:TextBlock = new TextBlock();
var font:FontDescription = new FontDescription(fontName);
var formt:ElementFormat = new ElementFormat(font, fontSize);
//following gives 'true EnglishF'
trace(FontDescription.isFontCompatible(fontName,"normal","normal"), formt.fontDescription.fontName);
formt.color = colr;
var span:TextElement = new TextElement(text, formt);
block.content = span;
_tl[0] = null;
_tl[0] = block.createTextLine(null, width);
var tl:TextLine;
// after here justification and addition lines
I will post something if and when I sort out why this doesn't work (Unless some kind person does it for me!)

ActionScript: How to Import XML data as a variable (not as an Event)

I am attempting to import some simple XML data into Flash ActionScript 3.0. I can easily do this as an import that is posted to the stage, but I want to save it as a global variable instead. Here is the XML file that I am pulling from:
<utilitySavings>
<nameof file="academicWaterSavings">
<waterValue>100</waterValue>
<elecValue>200</elecValue>
</nameof>
<nameof file="dormWaterSavings">
<waterValue>300</waterValue>
<elecValue>400</elecValue>
</nameof>
<nameof file="greekWaterSavings">
<waterValue>500</waterValue>
<elecValue>600</elecValue>
</nameof>
<nameof file="totalWaterSavings">
<waterValue>1500</waterValue>
<elecValue>1600</elecValue>
</nameof>
...and here is the actionscript:
var req:URLRequest = new URLRequest("data.xml");
var loader:URLLoader = new URLLoader();
var utilitySavings:XML;
function xmlLoaded(event:Event):void
{
utilitySavings = new XML(loader.data);
academicWater.text = utilitySavings.nameof[0].waterValue;
academicElec.text = utilitySavings.nameof[0].elecValue;
var dormWater:String = utilitySavings.nameof[1].waterValue;
trace (dormWater);
}
loader.addEventListener(Event.COMPLETE, xmlLoaded);
loader.load(req);
trace(academicWater.text);
Notice the 'trace (dormWater)' I want to trace this outside of the function so it is accessible in later in my script. I can trace within the function, but this does me no good. I also am able to get the dynamic text to show up on the stage but, likewise, this does me little good.
I appreciate any help or insights.
I can see a couple of ways of achieving this , if you want to create a globally accessible Object, create a Singleton( not recommended ) , load your XML data into it then every object in your app will be able to access the loaded XML data.
http://www.gskinner.com/blog/archives/2006/07/as3_singletons.html
The resulting code would give you something like this:
//Available throughout your app after the XML has been loaded & parsed
var dormWater:String = Singleton.dormWater;
Although you state you don't want Events, I think that using Signals could be a better approach. Load your XML and dispatch a Signal containing the relevant String to the object that needs it, when receiving the Signal , assign the String to a variable.
http://www.peterelst.com/blog/2010/01/22/as3-signals-the-best-thing-since-sliced-bread/
//In a specific class
private var _dormWater:String;
private function signalListener(value:Object ):void
{
_dormWater = value.dormWater;
}