Now given AIR is still a beta release, I hope what I present below will not be needed in the future because this took a while to figure out. Maybe I missed something, so if anyone points out an easier way to do this, I'm all ears.
It seemed the obvious thing to do is something along the lines of:
var data:BitmapData = e.transferable.dataForFormat(TransferableFormats.BITMAP_FORMAT) as BitmapData; myCanvas.addChild(data.content);
Burn! The bitmapData object appears to have data; it has height, width and rectangle properties, the size value indicates there's data in there, but when attempting to add the image to myCanvas, addChild reports an error of 'child must be non null'. I just couldn't reach in and get at the bits.
This led me down a rosy path of trying just about everything I could think to get that pretty picture I wanted to drag in. I ended up with the following. It basically serializes the transfer object's data to file, then I simply pick it back up as an image (note there are no format checks or validation in this example... study purposes only).
Note that you will need the PNGEncoder class, adopted by Adobe from Tinic Uro. These are working versions for Flex 2 and 3.
JPGEncoder.as (text)
PNGEnc (text)
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
applicationComplete="init()" layout="absolute">
<mx:Script>
<![CDATA[
import flash.filesystem.*;
import flash.geom.Matrix;
import flash.display.IBitmapDrawable;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.desktop.*;
import flash.events.NativeDragEvent;
import mx.controls.Image;
public function init():void {
myCanvas.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, nativeDragEnter);
myCanvas.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, nativeDragDrop);
}
public function nativeDragEnter(e:NativeDragEvent):void {
if (DragManager.dragInitiator == myCanvas) return; // If your dragging over yourself, ignore
DragManager.acceptDragDrop(myCanvas);
}
public function nativeDragDrop(e:NativeDragEvent):void {
var data:BitmapData = e.transferable.dataForFormat(TransferableFormats.BITMAP_FORMAT) as BitmapData;
var img:Image = encodeImage(data);
myCanvas.addChild(img);
}
private function encodeImage(data:BitmapData):Image {
// write transfer object's data to file
var stream:FileStream = new FileStream();
var matrix:Matrix = new Matrix();
matrix.translate( 0 - ( data.rect.x + 1 ), 0 - ( data.rect.y + 1 ) );
data.draw( data, matrix );
var png:* = null;
png = PNGEncoder.encode(data);
var file:File = File.applicationResourceDirectory.resolve( "tmp.png" );
stream.open( file, FileMode.WRITE );
stream.writeBytes( png, 0, 0 );
stream.close();
// now we can load the image back in
var img:Image = new Image();
img.load(file.nativePath);
return img;
}
]]>
</mx:Script>
<mx:Canvas id="myCanvas" width"400" height="300" backgroundColor="#FFFFFF">
</mx:Canvas>
</mx:WindowedApplication>
Now, with the added call in the nativeDragDrop() function, we have what we need:
var data:BitmapData = e.transferable.dataForFormat(TransferableFormats.BITMAP_FORMAT) as BitmapData; var img:Image = encodeImage(data); myCanvas.addChild(img);
Simple? Not exactly. Obvious? Certainly not! But, it shows that Flex can do quite a lot, with a little elbow grease. I am looking forward to the next AIR release, which should fix a number of other bugs and missives that will make our apps really fly.
Why not just:
ReplyDeletevar pic:Bitmap = new Bitmap();
pic.data = data;
myCanvas.addChild(pic);
I only wish it were that simple Joe. A Bitmap object doesn't have a data property though. And, the docs for TransferableFormats.BITMAP_FORMAT specify BitmapData, not Bitmap, as the return type. Like I say, the image data is in the transfer object, but it's either completely transparent, or it's a bug with the beta.
ReplyDeleteGonna keep trying various angles and will post my findings. FWIW, I'm also attempting to paste an image from the new ClipboardManager in Flex 3, and my method above doesn't work on it - humph! Even Kevin Hoyt over on his blog acknowledges the problem.
what about this link...
ReplyDeletehttp://www.cynergysystems.com/blogs/page/andrewtrice?entry=flex_2_bitmapdata_tricks_and
In my system i am getting an error in the line,
ReplyDeletepng = PNGEncoder.encode(data);
Error message:- 1061: call to possibly undefined method encode through static type Class
Paritosh, did you pull down the encoder class and add it to you project? You can get it from http://labs.adobe.com/svn/flashplatform/?/projects/corelib/trunk/src/actionscript3/com/adobe/images/PNGEncoder.as
ReplyDeleteHi Greg,
ReplyDeleteI just want an example from you how to copy and paste an image in our AIR application. That is instead of drag drop I just want copy and paste.
Thanx,
Paritosh
I'm swamped at the moment, but I'll try to get you a clipboard example in a few days.
ReplyDeleteA solution for rendering raw bitmap data in a flex/air application can be found on this blog website
ReplyDeleteI was just wrestling with a similar issue. The "simple" solution I found is to create a Bitmap object to hold the BitmapData, then add the Bitmap as a child of an Image, then add the Image as a child of your canvas (or whatever object you want it to appear in).
ReplyDeleteWith your code, that would look something like this:
var data:BitmapData = e.transferable.dataForFormat(TransferableFormats.BITMAP_FORMAT) as BitmapData;
var bitmap:Bitmap = new Bitmap(data);
var img:Image = new Image();
img.addChild(bitmap);
myCanvas.addChild(img);
Warning: I haven't tested this code, so please take it as an example of the concept.
Good luck figuring this out!
Carolyn,
ReplyDeleteYour code did work as you outlined. Thanks!
- Rich
Hi,I have an image and i want to remove white color from image.That removing color is same like its background color.If anybody have any idea of this problem please reply me on mitesh@clientdriveninnovation.com .And my application in Flex 3 so please send me action script code of this problem.Thank you
ReplyDeleteGreat tutorial! I have also created a tutorial about native drag and drop support in adobe air with source code included. Do check it out as well.
ReplyDeleteAdobe AIR Training
ReplyDeleteproducts are empowering business to manage application environments based on their specific needs. It allows developers to build and deploy applications quickly and easily