Flex: Image snapshot and File save service

jacopo3001's picture

i broke my head on this for few days (and broke anyone on this group's b##ls i guess..)
i got to a solution now and want to share:

i am on drupal 6.10, Services, amfphp.
I have a content type called PHOTOS with 1 image_field.
I need to save the image to server, store it into drupal, then finally create/edit the node to link the image file to it.

My starting point is very similar with keystr0k's @ http://groups.drupal.org/node/20549, with the difference that he's using DrupalSite.as class.
I tried keystr0k's method and it didnt work for me, and it was too complex to debug.

Keystr0k's work was anyway a huge help to figure out how to write the functions.

First step is to add a FILE.SAVE method to the file_service service. Get the patch here: http://drupal.org/node/376226.
This patch let you both save the file to the server and to store it into drupal's file table.

The MXML would then look like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" height="485" width="556">
  <mx:Script>
    <![CDATA[

import mx.controls.;
import mx.rpc.events.
;
import mx.utils.Base64Encoder;
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.*;

public function onFault(event:FaultEvent):void{
   Alert.show(event.fault.faultString, "Error");
}

public function nodeSaveResult(event:ResultEvent):void{
mx.controls.Alert.show("Node saved", "Success");
}

public function fileSaveResult(event:ResultEvent):void{
    var fid:int = event.result.toString();
if(fid > 0){
        saveNode(fid);
}
}

public function saveImage():void{
var jpgEnc:JPEGEncoder = new JPEGEncoder(100);
var ohSnap:ImageSnapshot;
  ohSnap = ImageSnapshot.captureImage(img, 0, jpgEnc); // capture image file. you can change this to almost anything you want on the canvans
var photoBase64:String = ImageSnapshot.encodeImageAsBase64(ohSnap);
    var fileObj:Object = {
     file:photoBase64,
                fid:"",
                filepath:"photos/photo.jpg", //should be dynamic & variable-driven!
                filesize: ""
   };
file.save(fileObj);
}

public function saveNode(fid:int):void{
    var nodeObject:Object = new Object();
        nodeObject.type = "mytype";
        nodeObject.nid = nid.text; // set to zero to create new node
        nodeObject.title = title.text;
        nodeObject.body = body.text;
        nodeObject.created = "2009-1-14"; // @make this dynamic. for some reason get_time() does not work for me 
        nodeObject.field_image = new Array({ fid:fid });
        node.save(nodeObject);
}

]]>
</mx:Script>
<mx:RemoteObject endpoint="http://localhost/flextest/services/amfphp" showBusyCursor="true" destination="amfphp" source="node" id="node">
   <mx:method name="save" result="nodeSaveResult(event)" fault="onFault(event)"/>
</mx:RemoteObject>
<mx:RemoteObject endpoint="http://localhost/flextest/services/amfphp" showBusyCursor="true" destination="amfphp" source="file" id="file">
  <mx:method name="save" result="fileSaveResult(event)" fault="onFault(event)"/>
</mx:RemoteObject>

<mx:Image x="15" y="213"  id="img" source="@Embed('base_media.jpg')" />
<mx:Label x="10" y="10" text="Save Node" fontWeight="bold"/>
<mx:Label x="10" y="38" text="Node ID:"/>
<mx:Label x="10" y="65" text="Title:"/>
<mx:Label x="10" y="91" text="Body:"/>
<mx:TextArea x="84" y="64" width="161" height="19" id="title" text="some title"/>
<mx:TextArea x="84" y="90" width="161" height="51" id="body" text="some body"/>
<mx:TextInput x="84" y="36" text="0" width="44" id="nid"/>
<mx:Button label="Save File" click="saveImage()"  x="113" y="220"/>
</mx:Application>

i know it's not the perfect coding, but it works.

a basic tutorial on how to create/edit a node (without file) from flex can be found here:
http://drupal.org/node/178085 (including notes about DATE and CCK fields..)

feel free to give feedback. thanks

Groups:
Login to post comments

Cheers for this. I have

BeechyBoy's picture
BeechyBoy - Sat, 2009-09-05 18:54

Cheers for this. I have managed to get nearly all the way there, but I'm using Flash CS3. Any tips for doing this in Flash AS3... as opposed to Flex. Flash doesn't have ImageSnapshot or Base64Encoder in-built. What can I do?