How to load a blob from a PHP backend into Flex

For a while I had some trouble with figuring this one out, so I wanted to share this with you, because maybe this can save you some sleepless nights.

You see, I had a situation where I stored some small icon images in a MySQL database and I wanted them coming back from a server call using AMFPHP, so I could display them as an image in a Flex application. So you might think this can’t be hard to do. And you’re right, but there are some minor issues you have to keep in mind.

First of all, there was the problem that the image wasn’t transferred correctly. Everytime I debugged the server call. The backend part seemed fine, but the value I was getting returned from the call, was just plain rubbish. It took me a while to figure this one out, but the answer to this problem was very simple. Because image data contains some weird characters, the stream send over AMF was prematurely terminated. That is why the image couldn’t be shown. I managed to solve this by encoding the stream using a Base64Encoder in PHP, before sending it to Flex.

Now I still had to put the actual image on screen. What I needed to do, was to decode the byte stream again with de Base64Decoder class from Flex. That decoded stream actually contains the image information. Now I had to find a way of showing that information in some Flex component. The answer to this one was more obvious than I had dared to imagine. I started out looking at ByteArray conversions into BitmapData and putting that data into a Bitmap component. But everytime I got one step closer to the solution (or so I thought) I actually went one step further away from it… Until it hit me hard in the head that I could just use an Image component. This is not really well documented in my opinion, but besides a file name, you can also provide a byte stream to the source property of an Image component. Knowing that, I just had to set this property to the image information, using the toByteArray() method of the Base64Decoder class.

O boy, sometimes life can be much easier than you think…

Share
back

16 comments

  1. David Ethell says:

    Can you post some sample code? We’re trying the same thing. I have JPEG images stored in MySQL and I can pull them back out in PHP and display them fine in html.

    When we send them to Flex through AMFPHP we first use base64_encode to encode the data. Then in Flex we’re using Base64Decoder to decode the string, but we’re getting unknown file type problems when trying to load the ByteArray into an image object.

  2. Hi David,

    It’s been a while since I posted this, so I had to search for the code again, but finally I’ve found it.

    There doesn’t seem to be anything wrong with your code. I also do the base64_encode() in php. However, I use a PNG file and sent it back to Flex in an XML structure, using remoting. So I get an XMLListCollection back from the backend. Perhaps these are some things that are different between us.

    In Flex I then have an IconRenderer which does the decoding as follows:
    var dec:Base64Decoder = new Base64Decoder();
    // Decode the image data. In my case it’s in an attribute of the XML
    dec.decode(data.@logo);
    // img is just a plane Image object for which I set the source
    img.source = dec.toByteArray();

    That’s all there is to it. I hope this helps out.

  3. David Ethell says:

    Thanks for replying. Your post put us past the hump. We were loading JPEG files and for some reason Flex couldn’t detect the file type from the ByteArray. We changed the upload side of things to convert everything to PNG instead and now Flex can see the images just fine. So for some reason Flex has trouble detecting the file type of a JPEG file but not of a PNG file.

    Thanks again!

    David

  4. David,

    Thanks for posting this back to me, because I’m currentle in a similar situation where I need to display a JPEG ByteArray. I also tried the Base64Image component of flexlib component library, but so far I’ve had no luck with that either.

    Rest assured, when I find the solution for this problem I will post it here also. This shoul be possible since the only image format I know off that gives Flex some troubles is a BMP file. If you can load a JPG at runtime, you should be able to do it using a ByteArray…

  5. vuthecuong says:

    Could you post a tutorial about how to load a blob from a PHP/SQL backend into Flex whith source code example or could you give some usseful links of this tutorials?
    Please help me. I need your help.
    THanks in advanced

  6. cuongtt says:

    Dear David & Steven,

    First, I would like to thanks you two for sharing your experiene. I ‘m dealing with the same problem but I could load both PNG and JPG into MySQL and then retrieve it back from Flex 3, I think mayb I ‘m in luck and at this time mayb both of you figure out how to it, but if you haven’t , tell me :D

  7. Dear vuthecuong,

    If you look at my comment of Sept. 26, you should have all the code that is necessary for doing this. The retrieval of the blob is just a simple select statement. The other code that is necessary is written out in that comment.

    Steven

  8. Satish says:

    Hi Steve,

    I have been working on this task from last 7 days, but couldn’t figure out how to do it, here is the summary of my task:

    in my application, user has an option to upload a picture for his profile. I am currently using filereference method to upload the picture and convert it to bytearray and pass the bytearray to backend php code to upload in to mysql database.when I tried inserting in the mysql, i dont know why is it not recognizing the bytearray it recceives from front end?. It is just inserting a blank row in mysql. I am sure we have to do some processing on the bytearray before inserting in to mysql. can you please suggest me on my Issue.

    Thanks in Advance,

    Satish

  9. Hi Satish,

    The only things I can think of right now is that either your SQL statement has an error (e.g. no single quotes) or that you forgot to base64 encode your data. Without the actual code, I’m afraid there’s not much else I can say.

    But on the other hand I wonder if it wouldn’t be simpler for you if you were to handle the insert from within a file upload script? That way, you just read the file in PHP and don’t have to worry about encoding issues. Just a thought…

    Cheers,
    Steven

  10. Satish says:

    Hi Steve,

    Thank you very much for replying. To make it clear about my situation, Here’s my code:

    Flex Side:

    ///////////File Reference method/////////////////

    private function getFile():void
    {
    _fileRef=new FileReference();
    _fileRef.addEventListener(Event.SELECT, onFileSelect);
    _fileRef.browse();
    }

    private function onFileSelect(e:Event):void
    {
    _fileRef.addEventListener(Event.COMPLETE, onFileLoad);
    _fileRef.load();
    }

    private function onFileLoad(e:Event):void
    {
    var loader:Loader=new Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
    loader.loadBytes(_fileRef.data);
    }

    private function onImageLoaded(e:Event):void
    {
    var loadedBitmap:Bitmap=Bitmap(e.target.content);
    var scale:Number=getScale(loadedBitmap);
    var bmpData:BitmapData=new BitmapData(loadedBitmap.width * scale, loadedBitmap.height * scale, false);
    var matrix:Matrix=new Matrix();
    matrix.scale(scale, scale);
    bmpData.draw(loadedBitmap, matrix)
    var jpg:JPEGEncoder=new JPEGEncoder(60);
    _imageByteArray=jpg.encode(bmpData);
    imageuploadserv.send(); ///////HTTP Service/////////////////
    }

    private function getScale(img:Bitmap):Number
    {
    var scale:Number;
    if (img.width > MAX_SIZE)
    {
    scale=MAX_SIZE / img.width;
    }
    else if (img.height > MAX_SIZE)
    {
    scale=MAX_SIZE / img.height;
    }
    else
    {
    scale=1;
    }
    return scale;
    }

    //////HTTP Service //////

    {_imageByteArray}////////////The Image Bytearray that is sent to PHP///

    ///////////////////////////PHP code to upload image in mysql///////

    with the above code i was able to upload image in mysql. i can see the data in the column with some weird characters, but i am not sure, if the image is uploaded correctly

  11. Satish says:

    Hi Steve,

    for some reason php code cannot be seen in the above post, here is the upload php script

  12. Satish says:

    php code to upload image
    /////////////////////////////////////////////////

    $content = $_FILES['imagename']; /////bytearray received from Flex
    $table=”IMAGES”;
    $query = mysql_query(“UPDATE $table SET LOGO = ‘$content’ WHERE ID=’1′ “);
    if(!$query)
    {
    return “error=” . mysql_error();
    }

    else {

    return “success”;
    }

    //////////////////////////////////////////////////////

  13. Hi Satish,

    I notrice that you don’t put any Base64 encoding on the data (or maybe I missed it). I think that may be your problem. If you’re not using Base64 encoded strings, you may get something cut off (or other weird stuff) in transfer.

    So, I would suggest trying to encode the image data, send it to the back end and decode it before inserting it into the database. (or you can just leave it encoded as well, which saves you some PHP coding)

    Cheers,
    Steven

  14. Satish says:

    Hi Steve,

    Thanks for your suggestion. it finally worked. This is how I have done it:

    uploading:

    I have used file reference to upload the image and URL request to send the uploaded image to the php script. I have uploaded the image in mysql without modifying(encoding/decoding) the passed data.

    downloading:
    In the downloading php script after querying the mysql for image, i have encoded the image as you said and passed the encoded data to the flex side, where i have decoded the data and stored it as a bytearray, that’s it i used that bytearray as source to the image component.

    Thank a lot.

    Satish

  15. Prakash says:

    how to upload the vector images like svg in to flex 3 application

  16. Hi Prakash,

    You can’t load SVGs into Flex applications at runtime. Flex only support limited SVG functionality.

    One of the restrictions is that you can only embed the SVGs at compile time and not load them at runtime.

    Cheers,
    Steven

Leave a Reply

Your email address will not be published. Required fields are marked *

*