flex: Create a screenshot of UI element - actionscript-3

I want to make a screenshot of custom as3 ui element (which was extended from Canvas), and then upload the image on the server.
Could you help me with a small example of this?
I am trying to do the following:
// This is UI component extended from Canvas
var chessBoard:ChessBoard = new ChessBoard();
// I displayed pieces on the board, but didn't add it to the stage (I just need a
// a screenshot, not need them on the canvas)
chessBoard.displayPosition(DataStorage.getInstance().getStoredPosition(0));
var img:ImageSnapshot = ImageSnapshot.captureImage(chessBoard, 300, new PNGEncoder());
var obj:Object = new Object();
obj.complexity = complexity.value;
obj.img = img;
httpService.send(obj);
and getting this error:
ArgumentError: Error #2015: Invalid
BitmapData. at
flash.display::BitmapData() at
mx.graphics::ImageSnapshot$/captureBitmapData()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:186]
at
mx.graphics::ImageSnapshot$/captureImage()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:282]
at
ui::SendForm/send()[/Users/oleg/Documents/chess_problems/problemme/src/ui/SendForm.mxml:53]
at
> ui::SendForm/___SendForm_Button1_click()[/Users/oleg/Documents/chess_problems/problemme/src/ui/SendForm.mxml:16]
This error was caused by missing width and height of the Canvas. I set them and it helped to create bitmap data this way:
var bitmapData:BitmapData = new BitmapData(chessBoard.width,chessBoard.height);
var encoder:PNGEncoder = new PNGEncoder();
var data:ByteArray = encoder.encode(bitmapData);
I wonder how do I send the image to the server via httpService? Is there a way. Also is data = image file?

Here is a post on someone who has done this exact thing in AS3:
Dynamically Create an Image in Flash and Save it to the Desktop or Server

It is possible, and although I have never done it, this may be useful to you: http://www.flash-db.com/Tutorials/snapshot/

Related

How to display an image from URLRequest twice (downloading it only once)?

I am just wondering, if it is possible to load an image via URLRequest once, and display that image twice? Or do i have to load the image 2 times?
Edit:
Also want to ask if it is possible to duplicate the bitmaps when they are loaded in a loop(array).
For example:
var duplicate:Array = new Array(loadedArray.push(e.target.content));
When i am trying the code :
loadedArray.push(e.target.content);
var duplicate:Array = new Array(loadedArray.push(e.target.content));
It doesnt give me any errors, but from before it adds the bitmap with no problem, but now, it doesnt add anything.
And when i tried
var duplicate:Array = new Array(loadedArray as Bitmap);
addChild(duplicate[0]);
I have an error Error #2007: Parameter child must be non-null.
Duplicating Bitmap or BitmapData is easy. There are a lot of options, these are few of them:
// in your case, but can be any Bitmap
var original:Bitmap = Bitmap(loader.content);
// we actually need the bitmapData; separate for easy reading
var originalBitmapData:BitmapData = original.bitmapData;
var duplicate:Bitmap = new Bitmap(originalBitmapData);
// this one returns brand new copy of the BitmapData (sometimes needed)
var duplicate:Bitmap = new Bitmap(originalBitmapData.clone());
copyPixels() on BitmapData is also super fast and can be used for duplication, depending if there is already Bitmap(Data) instantiated.

bitmapdata.draw failing silently

I am trying to read an image using Loader (variable name is faceimage) and trying to pass the bitmapdata of that image to a function called detect. However, it is failing in the line where I am trying to get the Bitmap.
bmpTarget = new Bitmap( new BitmapData( faceImage.width, faceImage.height, false ) )
bmpTarget.bitmapData.draw( faceImage ); // Fails, no errors shown
detector.detect( bmpTarget.bitmapData );
I narrowed down to this line by putting trace statements above and below the failing line. The faceImage contains valid data which I verified by displaying contents on screen. I also tried
bmpTarget = Bitmap(BitmapData(faceImage.content))
but in vain. Am I doing something wrong here?
It could be a sandbox/crossdomain issue. Certain crossdomain settings prohibit drawing the content of a loaded image to a bitmapData. You can get around it by loading the raw image data with URLLoader and then using loadBytes on Loader.
As noted from:
Why do Loader objects kill bitmapdata draw();?
You likely need a LoaderContext.
loader.load("http://www.example.com/myimage.jpg", new LoaderContext(true));
Otherwise, you can load images from other sites but not access the actual bitmapData, which a draw() requires.
I wonder if you're trying to access the bitmapdata before it's been loaded?
Perhaps try using a complete listener...
var _urlRequest:URLRequest = new URLRequest("urlToImage");
var faceImage:Loader = new Loader;
faceImage.load(_urlRequest);
faceImage.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void{ trace(e) });
faceImage.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded, false, 0, true);
function imageLoaded(e:Event):void {
faceImage.contentLoaderInfo.removeEventListener(Event.COMPLETE, imageLoaded);
var bmpTarget:Bitmap = e.target.content;
detector.detect( bmpTarget.bitmapData );
}

AS3 BitmapData Collision Detection

So I'm working on a flash game where I'm using bitmapdata to determine collision detection with terrain. The idea was to have two sets of terrain tiles, one with the actual terrain on top and a simpler one with only a few basic colors to determine collision. That way if the hero comes into contact with a certain color on the "heightmap" his movement can be halted, slowed, he can receive damage or be scaled up and down to show variance in height. In order ot do this I need to add a whole bunch of heightmap tiles by means of an array, same way as I add the tiles themselves.
Doing this through bitmapdata is proving to be a lot more difficult than I expected and I keep running into errors when using the following code.
This is the Error that I get: TypeError: Error #1010: A term is undefined and has no properties.
As far as I can tell it's coming from the following bit of the code:
var bitmapData:BitmapData = new BitmapData(heightContainer.heightMapClip.width, heightContainer.heightMapClip.height);
But I have no idea what I'm doing wrong.
Here's the code in its entirety, though I haven't gotten around to the array part yet, just need to get this to work first and I really want to try and figure out the rest for myself:
var heightMapClip = new heightMap();
heightContainer.addChild(heightMapClip);
var heightData:String;
var hContainer:Sprite = new Sprite();
heightMapClip.x=-200;
heightMapClip.y=-200;
var bitmapData:BitmapData = new BitmapData(heightContainer.heightMapClip.width, heightContainer.heightMapClip.height);
bitmapData.draw(heightContainer.heightMapClip);
var myHeightMap:Bitmap = new Bitmap(bitmapData);
heightContainer.addChildAt(hContainer,0);
heightContainer.hContainer.addChild(myHeightMap);
heightContainer.hContainer.addEventListener(Event.ENTER_FRAME, onClick);
function onClick(e:Event):void
{
var obj:Sprite = e.currentTarget as Sprite;
var myHeightMap:Bitmap = Bitmap(obj.getChildAt(0));
var pixelValue:uint = heightContainer.myHeightMap.bitmapData.getPixel(mouseX,mouseY);
heightData=pixelValue.toString(16);
if(heightData=="99ff00"){
trace("Collision Detected");
}
}
Any help on this would be greatly appreciated.
heightContainer.addChild(heightMapClip);
by doing this you don't add property heightMapClip to the heightContainer
heightContainer.heightMapClip.width this will generate error
but this won't (as long as it exists and has width property:))
heightMapClip.width
best regards
p.s. "solved it by accident" doesn't specify solution. Write what you have done to answer to your question so others can see and learn from it.

flash as3 and external text config file

My goal was to have an external text file config for a client. I didnt want to go through a crazy xml thing, I just wanted it to be simple to change.
I started with a urlLoader, and was able to dynamically generate an object no problem. This is the function which parses and sets the properties of the object.
function onLoaded(e:Event):void//initializes the config
{
var myString = String(e.target.data);
//trace(e.target.data);
//trace(myString);
var propsArray:Array = myString.split("\n");
for (var i = 0; i < propsArray.length; i++){
var thisLine:Array = propsArray[i].split("=");
var thisPropName:String = thisLine[0];
thisPropName = thisPropName.replace(rex,'');
var thisPropValue:String = thisLine[1];
thisPropValue = thisPropValue.replace(rex,'');
trace("thePropName is: " + thisPropName);
trace("thePropValue is: " + thisPropValue);
config[thisPropName] = thisPropValue;
}
}
The text file would just look something like:
gateway = "http://thePathto/theFile.php
toast = sonofabitch
timer = 5000
xSpeed = 5.0
That way, I could just put a little bit of as3 code in, type what things I wanted configured, then all I would have to do was type config.timer and
var myTimer:Timer = new Timer(Number(config.timer));
I think the problem is load order and scope. The config.timer is not created yet, so the timer is unable to access the value of the config.timer.
I'd look at using XML in future projects of this nature, however to answer your question:
I think the problem is load order and scope. The config.timer is not created yet, so the timer is unable to access the value of the config.timer.
Correct, you will need to initialize your Timer within the onLoaded() method, as the data will be received asynchronously and is not available until this happens.
ok not long ago i had created a download manager that uses this exact concept.
The link below will take you straight to the website where you can download the full swf including my source files. also this website is a good place for resources
http://ffiles.com/flash/web_applications_and_data/dynamic_download_manager_3529.html
Below is my loader:
addEventListener(Event.ENTER_FRAME, update);
var myLoader:URLLoader = new URLLoader();
myLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
myLoader.load(new URLRequest("settings.txt"));
myLoader.addEventListener(Event.COMPLETE, onDataLoad);
function onDataLoad(evt:Event)
{
box1.text = evt.target.data.Id_1;
box2.text = evt.target.data.Id_2;
box3.text = evt.target.data.Id_3;
box4.text = evt.target.data.Id_4;
box5.text = evt.target.data.Id_5;
}
Add some dynamic text boxes to stage and name them "box1, box2 ect..."
Now creat your text file:
Id_1=this is what ever you want
&Id_2=this is what ever you want
&Id_3=this is what ever you want
&Id_4=this is what ever you want
&Id_5=this is what ever you want
Hope this helps.

How to convert bytearray to image or image to bytearray ?

How to assign bytearray value to panel background image. If anybody have idea or experiance plz help me to overcome the problem. BRIEF EXP:
I have panel control and want to load image getting from webservice as a backgroundimage. So i used setstyle() but its not accepting that image. so how to add that image into my panel background image.Plz tel me your ideas here.
In Flex 3 or higher, you just need to do:
yourImage.source = yourByteArray;
regards!
uhm, well i presume, since it is an image, you have it in a BitmapData, let's say "myBmp" ...
then use the following to extract all the data from BitmapData:
var bytes:ByteArray = myBmp.getPixels(myBmp.rect);
and the following to write:
myBmp.setPixels(myBmp.rect, bytes);
note that only the raw 32 bit pixel data is stored in the ByteArray, without compression, nor the dimensions of the original image.
for compression, you should refer to the corelib, as ozke said ...
For AS3 you can use adobe corelib. Check this tutorial...
http://ntt.cc/2009/01/09/as3corelib-tutorialhow-to-use-jpegencoder-and-pngencoder-class-in-flex.html
I used a flash.display.Loader() to load an image in an array. It has a Complete event that is fired after the image has been loaded. I then draw the image on to a Bitmap which I set to the data of a Image that could be placed in a panel. Hope you can make since of this good luck.
public static function updateImage(img:Image, matrix:Matrix,
pageDTO:PageDTO, bitmapData:BitmapData):void {
var loader:flash.display.Loader = new flash.display.Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (e:Event) : void {
bitmapData.draw(loader.content, matrix);
pageViewer.data = new Bitmap(bitmapData);
});
loader.loadBytes(pageDTO.thumbnail);
}
<mx:Panel>
<mx:Image id="pageViewer"/>
</mx:Panel>
Using adobe's JPGEncoder (com.adobe.images.JPGEncoder) class and ByteArray is pretty much all you need. Converting image to byte array (assuming CAPS are variables you'd need to fill in):
// -- first draw (copy) the image's bitmap data
var image:DisplayObject = YOUR_IMAGE;
var src:BitmapData = new BitmapData(image.width, image.height);
src.draw(image);
// -- encode the jpg
var quality:int = 75;
var jpg:JPGEncoder = new JPGEncoder(quality);
var byteArray:ByteArray = jpg.encode(src);
I had the same problem. As a workaround I created sub Canvas nested inside a main Canvas and added an Image to the main Canvas behind the sub Canvas. Anything drawn on the sub Canvas will appear on top of the Image.
Just load it into a Loader instance using the loadBytes function.
var ldr:Loader = new Loader();
ldr.loadBytes(myByteArray);
addChild(ldr);