Flex: Image snapshot and File save service

Events happening in the community are now at Drupal community events on www.drupal.org.
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

Comments

Cheers for this. I have

Fixdit's picture

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?

Download Flex SDK and link

japanitrat's picture

Download Flex SDK and link libraries as external libraries in Flash.

jacopo3001: Great stuff - exactly what I was looking for

Help with file ID & imagefield

lordpicklepuss's picture

Could you tell me how you got away with simply passing a fileid to the imagefield? It doesn't seem to be working for me. The rest of your code works great, though!

To be more specific

lordpicklepuss's picture

It's giving me the error message: Referencing to the file used in the myfield field is not allowed.

check the configuration for

japanitrat's picture

check the configuration for this filefield. did you allow the proper extension (jpg, gif, whatever you are trying to reference)?

Yes, that is set correctly.

lordpicklepuss's picture

Yes, that is set correctly. I've tried just about every combination of permissions, all services are enabled on my API key, and I'm stumped.

I seem to have stumbled

lordpicklepuss's picture

I seem to have stumbled across part of the solution. I'm not getting the error anymore, but my images are still not showing up in the filefield: http://drupal.org/node/721336#comment-2628940

Services

Group organizers

Group categories

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week