I was recently working with ways to hide (or obscure) images in an application's source code. I'm not sure there's many uses for encoding image data in a string; It's certainly not an easy or efficient way of working with images.
Never the less though here's a few notes on converting images to strings of byte data and back. First step was to write a small application that could load up an image and parse its data into a String format that could be copied/pasted/saved.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" layout="vertical" xmlns:net="flash.net.*" xmlns:display="flash.display.*">
<mx:Script>
<![CDATA[
[Bindable] private var text:String = "";
private var loader:Loader;
private function process( bytes:ByteArray ) :void
{
bytes.position = 0;
var str:String = "";
for(var i:int=0; i < bytes.length; i++)
{
var byte:String = bytes.readUnsignedByte().toString(16);
if(byte.length<2)
byte= "0" + byte; str += byte; } text = str;
}
private function load( ) :void
{
if(!loader) loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoadComplete );
loader.load( new URLRequest(urlInput.text) );
}
private function onLoadComplete( e:Event ) :void
{
process( (e.target as LoaderInfo).bytes );
}
]]> </mx:Script>
<mx:TextArea text="{text}" width="100%" height="100%" />
<mx:TextInput id="urlInput" width="100%" />
<mx:Button id="processBtn" label="Process" click="load( )" />
</mx:Application>
The main part of this is the process
method, which takes a ByteArray
and converts it into a string. In this case the bytes are supplied from the loaded image via the LoaderInfo
object. This application will then display the string in a big text area. (The string may well be very long!).
Second step is a little class that extends the Flex Image
component and adds one property, byteSource
, which it exposes as a getter/setter. Below is the code for the setter:
public function set byteSource( val:String ) :void
{
var newBytes:ByteArray = new ByteArray();
var dataArr1:Array = val.split("");
var dataArr2:Array = [];
for( var j:int=0; j < dataArr1.length; j+=2 )
{
dataArr2.push("0x"+dataArr1[j]+dataArr1[j+1]);
}
for( var k:int=0; k < dataArr2.length; k++ )
{
newBytes[k] = dataArr2[k]; } this.source = newBytes;
_byteSource = val;
}
}
This method takes a string like the one generated from the application above, converts it into a ByteArray
, and assigns that to the components source property. This component can now be added to any project, and supplied a string from which it will display an image. E.g.
<controls:ByteImage byteSource="{ImageObject.image}" />
Where ImageObject.image
is a static constant String of image data.