Reputation: 906
I have a flex program (AS3/Flash) that allows the user to create PNG images of portions of the stage and send them via email. This works swimmingly.
I want to take the same image and send it to the clipboard, but that does not work. So the next best thing is to allow them to send it to their browser, where they can save it to a file.
Here is the code that I am using to do that;
bmpPanelData.draw(uiPrintObject)
var baPanel:ByteArray = PNGEnc.encode(bmpPanelData);
// Clipboard.generalClipboard.clear();
// var bolClipboard:Boolean = Clipboard.generalClipboard.setData(ClipboardFormats.BITMAP_FORMAT, baPanel, true);
// trace('bolClipboard=' + bolClipboard);
var strFileName:String = strPrintObject;
var strFileExt:String = "png"
var variables:URLVariables = new URLVariables();
variables.mimeType = "application/octet-stream";
variables.fileExt = strFileExt;
baPanel.position = 0;
var strPanel:String = getBytes(baPanel);
// var strPanel:String = baPanel.readMultiByte(baPanel.bytesAvailable,"latin1");
variables.fileContents = escape(strPanel);
trace('strPanel.length=' + strPanel.length + ' baPanel.length=' + baPanel.length);
variables.disposition = "Attachment";
variables.fileName = strFileName;
var u:URLRequest = new URLRequest( RootDomain + "SendBinaryFile2.aspx");
u.data = variables;
u.method = "POST";
navigateToURL(u,"_blank");
}
catch (err:Error)
{
Alert.show("This Panel cannot be copied to the clipboard. \nSorry for the inconvenience \nError: " + err.errorID,"E-mail not premitted",Alert.OK)
}
(I left the clipboard stuff commented out in case someone knows how to do that. It is my understanding that you cannot send binary data to the clipboard from Flash, but it works in AIR.)
Since I could not find an AS3 method to convert a binary ByteArray to a string I wrote my own called getBytes. If you know of a method in AS3, please let me know.
private function getBytes(baArray:ByteArray):String
{
var strOut:String = "";
baArray.position = 0;
var intBASize:int = baArray.bytesAvailable;
for (var i:int = 0;i < intBASize;i++)
{
strOut += String.fromCharCode(baArray.readByte());
}
return strOut;
}
On the ASPX side I have a file called SendBinaryFile2.aspx that looks like this;
<%@ Page Language="C#" validateRequest="false"%>
<script Runat="Server">
void Page_Load(Object sender, EventArgs e)
{
string fileExt = Request.Form["fileExt"];
string mimeType = Request.Form["mimeType"];
string disposition = Request.Form["disposition"];
string fileName = Request.Form["fileName"];
byte [] fileContents = Encoding.ASCII.GetBytes(HttpUtility.UrlDecode(Request.Form["fileContents"]));
Response.Buffer = true;
Response.Clear();
Response.AddHeader("Content-Length", fileContents.Length.ToString());
Response.ContentType = mimeType;
Response.AddHeader("Content-Disposition", disposition + "; filename=" + fileName + "." + fileExt);
Response.BinaryWrite(fileContents);
Response.Flush();
Response.Close();
Response.End();
}
</script>
The results is a file that looks a whole lot like a .PNG file, but is corrupt when it is opened. I have visually compared the file sent via email, and the one sent via this program using VIM, and they look similar, have roughly the same number of characters, begin/end with similar characters.
Help on any of the items defined above is greatly appreciated.
Upvotes: 2
Views: 239
Reputation: 11
I'd suggest you use Base64 encoding to transport your binary data. You already must have needed to use it for encoding your email attachment, anyways.
Actionscript: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/utils/Base64Encoder.html
c#:
byte[] textAsBytes = System.Convert.FromBase64String(encodedText);
Also, if your SWF is running as standalone AIR (You wrote "Flex program"...), you can directly save files anywhere and give the user a "Save as..." prompt to do so.
Source to save from AIR:
var bmpd:BitmapData = new BitmapData(myWidth, myHeight, true, 0);
bmpd.draw(mySource);
var imgByteArray:ByteArray = new PNGEncoder().encode(bmpd);
var fl:File = File.desktopDirectory.resolvePath("myImage.png");
var fs:FileStream = new FileStream();
fs.open(fl, FileMode.WRITE);
fs.writeBytes(imgByteArray);
fs.close();
Upvotes: 1
Reputation: 15881
Try this for your getBytes
function...
private function getBytes (baArray:ByteArray) : String
{
var strOut:String = ""; var strRead:String = "";
baArray.position = 0;
var intBASize:uint = baArray.length;
for (var i:int = 0; i < intBASize; i++)
{
strRead = baArray.readUnsignedByte().toString(16);
if(strRead.length < 2) { strRead = "0" + strRead; } //# do padding
strOut += strRead ;
}
return strOut.toUpperCase();
}
This should give you padded bytes. Consider x0FF3
becomes just xFF3
without the padding, later the other side could be assuming the bytes are really xFF30
leading to corrupt images.
Upvotes: 2