Adobe AIR - Save image on hard drive - actionscript-3

I found the below snippet to save an image to a specific folder with Adobe AIR.
How to modify it that the "Save As" OS-window comes up first? (So users can choose where to save the image on the hard-drive)
var arrBytes:ByteArray = PNGEncoder.encode(bmd);
var file:File = File.desktopDirectory.resolvePath(folderName + "/" + fileName + fileNum + ".png");
var fileStream:FileStream = new FileStream();
//
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(arrBytes);
fileStream.close();
Thanks.

Use File.browseForSave:
import flash.filesystem.*;
import flash.events.Event;
import flash.utils.ByteArray;
var imgBytes:ByteArray = PNGEncoder.encode(bmd);
var docsDir:File = File.documentsDirectory;
try
{
docsDir.browseForSave("Save As");
docsDir.addEventListener(Event.SELECT, saveData);
}
catch (error:Error)
{
trace("Failed:", error.message);
}
function saveData(event:Event):void
{
var newFile:File = event.target as File;
if (!newFile.exists) // remove this 'if' if overwrite is OK.
{
var stream:FileStream = new FileStream();
stream.open(newFile, FileMode.WRITE);
stream.writeBytes(imgBytes);
stream.close();
}
else trace('Selected path already exists.');
}
The manual is always your friend :)
BTW, I see you're relatively new here - welcome to StackExchange! If you find my answer helpful, please be sure to select it as the answer.

Related

How do i save without a prompt

I found this code snippet i little while ago and found it useful in the app im creating for IOS and i´m trying to save and load this file in AS3 without it asking for a save/load file location and without the device prompting. I am using AIR for IOS
Just to be clear i just want it to save and load to a predetermined location (I.e the app folder).
i have typed in the code below.
stop();
// Timeline instances
var textField1:TextField;
var textField2:TextField;
var saveBtn:SimpleButton;
var loadBtn:SimpleButton;
saveBtn.addEventListener(MouseEvent.CLICK, saveClick);
function saveClick(e:MouseEvent):void {
// Save the state of both text fields
save(textField1.text, textField2.text, "SaveData.xml");
}
loadBtn.addEventListener(MouseEvent.CLICK, loadClick);
function loadClick(e:MouseEvent):void {
load();
}
function save(text1:String, text2:String, SaveData:String):void {
var xml:XML = <xml>
<text1>{text1}</text1>
<text2>{text2}</text2>
</xml>;
var file:FileReference = new FileReference();
file.save(xml, SaveData);
}
function load():void {
var file:FileReference = new FileReference();
file.browse([new FileFilter("XML", "*.xml")]);
file.addEventListener(Event.SELECT, loadSelect);
}
function loadSelect(e:Event):void {
var file:FileReference = e.target as FileReference;
file.addEventListener(Event.COMPLETE, loadComplete);
file.load();
}
function loadComplete(e:Event):void {
var file:FileReference = e.target as FileReference;
var xml:XML = XML(file.data.readUTFBytes(file.data.bytesAvailable));
// Assign the loaded XML text values back to the text fields
textField1.text = xml.text1;
textField2.text = xml.text2;
}
Saving file without prompt, or select dialog, or user consent whatsoever. As I mentioned before, no additional permissions required (I think) to write to File.applicationStorageDirectory location.
Implementation:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
function saveFile(fileName:String, fileData:String):void
{
var aFile:File = File.applicationStorageDirectory.resolvePath(fileName);
var aStream:FileStream = new FileStream;
aStream.open(aFile, FileMode.WRITE);
aStream.writeUTFBytes(fileData);
aStream.close();
}
Usage:
var X:XML = <xml>
<text1>{text1}</text1>
<text2>{text2}</text2>
</xml>;
saveFile("mytest.xml", X.toXMLString());

How do I write a huge bytearray to file progressively and avoid that dreaded memory error

I'm working on an Air project that downloads huge (zip) files, then unzips them and finally deletes the original .zip file it downloaded.
Everything's running smoothly except when I want to write the unzipped file to disk.
Trouble is, I keep running into the issue of this little monster of an error.
Error: Error #1000: The system is out of memory.
Here's the part of the code that is giving me grief. This works perfectly when the file is small (tested on a 3 MB file) but as soon as I try one of my large files (458 MB), I get the error.
private function unzipFile()
{
var pulledFile:FZipFile;
var index:int = 0;
var chunkSize:int = 1000000;
Console.log("Unzipping file...");
var zip:FZip = new FZip();
zip.addEventListener(Event.COMPLETE, onUnzipComplete);
var fileStream:FileStream = new FileStream();
zip.load(new URLRequest(urlToUnzip));
function onUnzipComplete(e:Event)
{
pulledFile = zip.getFileAt(0);
var file:File = File.documentsDirectory.resolvePath(pulledFile.filename);
fileStream.openAsync(file, FileMode.WRITE);
writeChunk();
}
function writeChunk()
{
var bytesToGet:int = pulledFile.content.bytesAvailable;
if (bytesToGet > chunkSize)
bytesToGet = chunkSize;
Console.log("Writing chunk " + (int((pulledFile.content.length - pulledFile.content.bytesAvailable) / chunkSize) + 1) + " of " + (int(pulledFile.content.length / chunkSize) + 1));
var fileData:ByteArray = new ByteArray();
pulledFile.content.readBytes(fileData, 0, bytesToGet);
fileStream.writeBytes(fileData, 0, fileData.length);
if (index < pulledFile.content.bytesAvailable)
{
writeChunk();
index += bytesToGet;
}
else
{
fileStream.close();
Console.log("Unzipping complete");
}
}
}
The code crashes specifically on the line
var bytesToGet:int = pulledFile.content.bytesAvailable;
How do I still progressively write content to a file without knowing how many bytes are available to me? If I don't have access to the bytesAvailable property, how do I know I'm done writing?
I'm using the FZip library for decompression.
This was tough, but I figured it out. The trick is to use the "serialize" method of the FZip and avoid touching the properties of the content ByteArrayaltogether.
Here's the final code that works.
private function unzipFile()
{
var pulledFile:FZipFile;
Console.log("Decompressing file...");
var zip:FZip = new FZip();
zip.addEventListener(Event.COMPLETE, onUnzipComplete);
var fileStream:FileStream = new FileStream();
zip.load(new URLRequest(urlToUnzip));
function onUnzipComplete(e:Event)
{
pulledFile = zip.getFileAt(0);
var file:File = File.documentsDirectory.resolvePath("Easywatch/" + pulledFile.filename);
fileStream.open(file, FileMode.WRITE);
zip.serialize(fileStream, false);
fileStream.close();
Console.log("Decompression complete");
}
}

AlivePDF not writing out text using addText(). Nothign I'm trying is working. What am I missing?

No matter what I try I can't write anything to a PDF that can be seen, although the text is there when viewing the resultant PDF in Notepad. What am I not doing? Here's a code snippet. the variable tf is a TextField defined in the class. This works in the SWF, just not with PDF.
private function onButtonClick(e:MouseEvent):void {
tf.text = "Hey, you clicked the button!";
myPDF = new PDF(Orientation.PORTRAIT, Unit.INCHES, Size.A4);
myPDF.setDisplayMode(Display.FULL_PAGE, Layout.SINGLE_PAGE)
myPDF.addPage();
myPDF.addText(tf.text, 20, 20 );
var filename:String = "Test-file.pdf";
var f:FileStream = new FileStream();
var file:File = File.userDirectory.resolvePath(filename);
f.open(file, FileMode.WRITE);
var bytes:ByteArray = myPDF.save(Method.LOCAL);
f.writeBytes(bytes);
f.close();
}

ActionScript 3: Get a File object's string value

I have my Flash project properties set for: AIR 3.4 for Desktop and ActionScript 3.0...
I created a button for the user to select a file (csv) from the local drive. I then want to be able to get the string value of the File Object but do not know how...
Here is what I have so far:
BTN_CSV.addEventListener(MouseEvent.CLICK, getCSV);
var myFile:File = new File();
function getCSV(e:MouseEvent):void {
var docFilter:FileFilter = new FileFilter("Documents", "*.csv");
myFile.browse([docFilter]);
myFile.addEventListener(Event.COMPLETE, completeHandler);
}
function completeHandler(event:Event) {
var csvData = myFile.nativePath;
csvData = csvData.data.split("\n");
parseCSV(csvData);
}
I'm getting an error 1061: Call to a possibly undefined method split through a reference with static type flash.utils: ByteArray. I don't know how to get the file path for the file obj...
The file class is basically just a pointer to the file you want.
Your code is almost there you just need to add in the FileStream class.
Source
import flash.filesystem.*;
import flash.events.Event;
var file:File = File.documentsDirectory;
file = file.resolvePath("Apollo Test/test.txt");
var fileStream:FileStream = new FileStream();
fileStream.addEventListener(Event.COMPLETE, fileCompleteHandler)
fileStream.openAsync(file, FileMode.READ);
function fileCompleteHandler(event:Event):void {
var str:String = fileStream.readMultiByte(fileStream.bytesAvailable, File.systemCharset);
trace(str);
fileStream.close();
}
[EDIT]
import flash.events.Event;
import flash.filesystem.File
import flash.filesystem.FileStream
import flash.filesystem.FileMode
var file:File =File.documentsDirectory;
file.addEventListener(Event.SELECT,onSelect)
file.browse()
function onSelect(event:Event):void{
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var str:String = fileStream.readMultiByte(file.size, File.systemCharset);
trace(str);
}

save image in a directory in applicationStorageDirectory

I was trying to save an imagefile to a directory in applicationStorageDirectory of my air project. Created the directory first
var imageDirectory:File = File.applicationStorageDirectory.resolvePath("vispics");
if (imageDirectory.exists)
{
Alert.show("Directory Already Exists");
}
else {
imageDirectory.createDirectory();
Alert.show(imageDirectory.nativePath);
}
The next part is saving image from my cam right now it saves to the applicationStorageDirectory. Here is how i do it
var randInt:int = Math.random() * (99999 - 1001) + 1001;
var randStr:String = randInt.toString();
var filename:String = ""+randStr+".jpg";
var file:File = File.applicationStorageDirectory.resolvePath( filename );
var wr:File = new File( file.nativePath );
var stream:FileStream = new FileStream();
stream.open( wr , FileMode.WRITE);
stream.writeBytes ( imageData, 0,imageData.length );
stream.close();
Is there a way that i can store the image in my "vispics" directory?
Thanks in advance.
Try:
var file:File = File.applicationStorageDirectory.resolvePath("vispics/" + filename);