Link to home
Start Free TrialLog in
Avatar of robbersrow
robbersrow

asked on

How do I display images from my database to my Flex application?

How do I display images from my database to my Flex application?  I'm using Rails 2 for the backend, Flex 3 for the frontend, and RubyAMF remoting to communicate between Rails and Flex.  Currently, I successfully retrieve the binary filedata from the database via RubyAMF remoting, and then have it available to display in Flex.  I would ideally like to then directly supply this data to the "Image" control in Flex.  I am stuck on this because the Flex "Image" control has a "source" attribute which only accepts the path to the image as a server filesystem path or a full URL (eg. /public/images/myimage.gif).  However, it does not appear that the "source" attribute accepts actual binary filedata which I am trying to supply to it.  
<mx:Image id="theImage" source="{data.picture}"/>

Open in new window

Avatar of Gary Benade
Gary Benade
Flag of South Africa image

Save the code below as ByteArrayImage.as in folder com/gary

<gary:ByteArrayImage id="theImage" />

On the loaded event you would then call
theImage.byteArrayData = data.picture;
package com.gary
{
	import flash.display.Loader;
	import flash.events.Event;
	import flash.utils.ByteArray;
	
	import mx.controls.Image;
 
	public class ByteArrayImage extends Image
	{
		private var ldr:Loader;
		public function ByteArrayImage()
		{			
			super();
		}
		public function set byteArrayData( b:ByteArray):void
		{
			ldr = new Loader();
			ldr.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoaded);
			ldr.loadBytes( b, null);
		}
		private function onLoaded( e:Event):void
		{
			ldr.contentLoaderInfo.removeEventListener( Event.COMPLETE, onLoaded);
			this.width = e.currentTarget.width;
            this.height = e.currentTarget.height;		
            this.source = ldr.content;	
		}
	}
}

Open in new window

Here is a test app for the ByteArrayImage component, substitute any jpg you have for 1.jpg
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:gary="com.gary.*">
	<mx:Script>
		<![CDATA[
			import mx.graphics.codec.JPEGEncoder;
			private function loadByteArray():void
			{
				var j:JPEGEncoder = new JPEGEncoder(50);	
				bai.byteArrayData = j.encode( (img.content as Bitmap).bitmapData);
			}
		]]>
	</mx:Script>
	<mx:Image id="img" x="10" y="10" width="428" height="320" source="1.jpg" complete="loadByteArray()"/>
	<gary:ByteArrayImage id="bai" x="446" y="10" width="427" height="320" />
</mx:Application>

Open in new window

Avatar of robbersrow
robbersrow

ASKER

This is very close to what I need to get working.  I tried your example code in my project, but substituting your line #9 from the Application code with my binary file data (see the attached code snippet).  In place of "img.content" I have a String variable which is holding the binary image filedata that I need to display.  However, when I put this String variable in place of where you have "img.content", no image appears, it is just blank.  Is it possible that there are different or additional conversions that must be done before JPEG encoding the raw binary filedata?  Can you think of anything else I might be missing?
***someObject.picture is a String containing raw binary filedata (ie. 380,000 chars)
 
bai.byteArrayData = j.encode((someObject.picture as Bitmap).bitmapData);

Open in new window

Your data is already jpeg encoded, so all uou need to do is

var b:ByteArray = new ByteArray();
b.writeUTFBytes( someObject.picture);
bai.byteArrayData = b;
I tried doing it this way, but I am still getting no image.  I used the following code to confirm that "someObject.picture" is over 385681 characters long.  I did this test after running through the code you recommended, as you can see in the code snippet below.

Also, I receive the following error as a result of the line "bai.byteArrayData = b;" (when I comment out this line, I do not receive the error).

Error #2044: Unhandled IOErrorEvent:. text=Error #2124: Loaded file is an unknown type.


Can you think of what is happening here?
private function loadByteArray():void 
{
  var b:ByteArray = new ByteArray();
  b.writeUTFBytes(someObject.picture);
  bai.byteArrayData = b;
 
  //pops up with the number: 385681
  Alert.show(someObject.picture.length.toString());
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Gary Benade
Gary Benade
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your help with this.  I think you are right about the storage of binary data in a string.  I will choose a different implementation, writing the image file to the filesystem and storing the path to reference it from the application.  It sure would be nice to figure out how to transfer binary data successfully over RubyAMF at some point.