bitmapdata.draw failing silently - actionscript-3

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 );
}

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.

PurePDF ImageElement throwing errors

Hey so I am trying to create an air app that generates a PDF for the user to save but am running into issues with PurePDF. Whenever I run the ImageElement.getInstance() method I am returned a runtime error:
Error: Error #2030: End of file was encountered. at flash.utils::ByteArray/readUnsignedByte()
I am still just in the testing stage and am not evening doing anything crazy. This is what my code looks like:
var bd:BitmapData = new BitmapData( 1024,768 );
bd.draw(pdfClip); //A simple movieclip on the stage containing an image
var bytes:ByteArray = bd.getPixels(new Rectangle(1024,768));
var image:ImageElement = ImageElement.getInstance( bytes );
I would be grateful if anyone that has used purePDF can offer any advice, the documentation is extremely limiting.
You should use the "getBitmapDataInstance" instead, because the "getInstance" method is expecting a png encoded bytearray.
ImageElement.getBitmapDataInstance( bitmap );
see also this example:
https://code.google.com/p/purepdf/source/browse/examples/src/ImageBitmapData.as

Action Script 3 new loader

I was revisiting some code for a simple picture viewer that I created in Action Script 2.0 now taking on the same task in AS3. At present i'm well aware that the command .loadMovie is no longer used. After numerous attempts to find a solution I have come up dry.
At the moment I have a movie clip symbol(target_mc) on the stage that I want to load jpegs from a external file when I mouseOver a button. Can any one give a example of how this should be approached using the "new load" variable.In the AS2 version i also used (on release) in the button code.
training_btn is the button instance.
Please see an example of my code below:
training_btn.addEventListener(MouseEvent.CLICK, imageOver);
function imageOver(evt:MouseEvent) {
this.target_mc.loadMovie("galleryimage/p_traininglink.jpg")
}
Any ideas would be very helpful.
Wayne
Here at the Republic of Code is an excellent step-by-step tutorial on how to work with the loader class in as3
Yeap
training_btn.addEventListener (MouseEvent.MOUSE_UP, onMouseUp);
function onMouseUp (evt:MouseEvent):void {
var my_loader:Loader = new Loader();
my_loader.load(new URLRequest("myPhoto.jpg"));
target_mc.addChild(my_loader);
}
So, basically the whole structure of the laoder has change between AS 2 and 3.
Now you need to create a different object that loads the content.
var loader:Loader = new Loader();
Than you can do two things:
Add event listener and than trigger the load
Trigger the load and add the loader to the stage
The difference between these two style is big, the first one will add a listener and wait for the load to complete and after that it will call a method you define in the listener to do any further instuctions.
The second one starts loading the content and adds the loader to the display list so that when the content is loaded it automatically displays.
1.
// add the listener
laoder.contentLoaderInfo.addEventListener( Event.Complete, onLoadComplete );
// trigger the load (remember: the url is alwais a URLRequest object)
loader.load( new URLRequest("path_to_file") );
// additional var for storing the content (only the content, without the loader)
var content:Bitmap;
function onLoadComplete( e:Event ):void{
content = e.target.content as Bitmap;
// you could use also:
// content = loader.content as Bitmap;
// you can do some modifications before displaying the content
// and finally add it to the display list
this.target_mc.addChild( content );
}
2)
// trigger the load (remember: the url is alwais a URLRequest object)
loader.load( new URLRequest("path_to_file") );
this.target_mc.addChild( loader );
The two ways are correct but I prefer using the first one cause it gives you more controll. You can also check out the progress of loading by listening to the ProgressEvent.PROGRESS.
link: Loader Documentation
link: URLRequest Documentation
Hope it helps. Search in google for more info about loading external data, there's a lot of resource about that.
It would probably best to create a Class that would handle all of this, but to answer your question, your code would look something like:
var outLoader:Loader = new Loader();
outLoader.load(new URLRequest("outImage.jpg"));
var overLoader:Loader = new Loader();
overLoader.load(new URLRequest("overImage.jpg"));
overLoader.visible = false;
var training_btn:Sprite = new Sprite();
training_btn.addChild(outLoader);
training_btn.addChild(overLoader);
training_btn.buttonMode = true;
training_btn.mouseChildren = false;
training_btn.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
training_btn.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
addChild(training_btn);
function rollOverHandler(e:MouseEvent):void {
overLoader.visible = true;
}
function rollOutHandler(e:MouseEvent):void {
overLoader.visible = false;
}

flex: Create a screenshot of UI element

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/

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);