I would like to get a ByteArray from a BitmapData in AS3. I tried the following:
var ba:ByteArray = myBitmapData.getPixels(0,0);
It didn't work and I got this error ArgumentError: Error #1063: Argument count mismatch on flash.display::BitmapData/getPixels(). Expected 1, got 2.:
As Adobe said about BitmapData.getPixels : "Generates a byte array from a rectangular region of pixel data...", so your parameter should be a Rectangle object.
Take this example from Adobe.com :
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
var bmd:BitmapData = new BitmapData(80, 40, true);
var seed:int = int(Math.random() * int.MAX_VALUE);
bmd.noise(seed);
var bounds:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var pixels:ByteArray = bmd.getPixels(bounds);
As was mentioned in the other answer, getpixels expects a .rect meaning rectangular area of some displayObject (like Sprite, MovieClip, Shape or other already exisiting BitmapData.
getPixels(). Expected 1, got 2. is becuase it should have been:
var ba:ByteArray = myBitmapData.getPixels( myBitmapData.rect);
Study this code and see if it helps you :
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.BitmapData;
var ba:ByteArray = new ByteArray;
var picBMP:Bitmap; var picBMD:BitmapData;
var pic_canvas:Sprite = new Sprite(); //container for image
var loader:Loader = new Loader(); //image loader
loader.load(new URLRequest("pic1.jpg")); //load some JPG/PNG/GIF/SWF
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, img_load_Complete);
function img_load_Complete(evt:Event):void
{
picBMP = loader.content as Bitmap;
pic_canvas.addChild(picBMP);
stage.addChild(pic_canvas); //container now added to stage (screen)
BMP_toBytes(); //do function to convert to bytes
}
function BMP_toBytes():void
{
var PC = pic_canvas; //shortcut reference to pic_canvas (less typing)
picBMD = new BitmapData(PC.width, PC.height, true, 0xFFFFFF);
picBMD.draw(PC); //make bitmapdata snapshot of container
ba = picBMD.getPixels(picBMD.rect);
trace("BA length : " + ba.length); //check how many bytes in there
ba.position = 0; //reset position to avoid "End of File error"
bytes_toPixels(); //do function for bytes as pixels to some new container
}
function bytes_toPixels():void
{
var new_BMP:Bitmap = new Bitmap; var new_BMD:BitmapData;
var new_canvas:Sprite = new Sprite(); //another new container for pixels
ba.position = 0; //reset position to avoid "End of File error"
//we can reuse picBMD W/H sizes since we have copy of same pixels
new_BMD = new BitmapData(picBMD.width, picBMD.height, true, 0xFFFFFFFF);
new_BMD.setPixels(new_BMD.rect, ba); //paste from BA bytes
new_BMP.bitmapData = new_BMD; //update Bitmap to hold new data
new_canvas.x = 150; new_canvas.y = 0; new_canvas.addChild(new_BMP);
stage.addChild(new_canvas); //add to screen
}
Hope it helps..
Related
I am having trouble embedding a child object to a movieClip with code using AS3 and I am not sure what I am doing wrong.
I am trying to create a new movieclip with code and add it to the stage. I am then trying to embed dynamically created objects inside that movieclip. When I trace the objects it shows that they are on the stage and not embedded into the movieclip. I looked through the forums but I didn't find an answer. Below is a watered down version of the code I have. Any help is appreciated.
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Sprite;
import flash.text.*;
import flash.net.URLRequest;
import flash.display.Loader;
var btnAImage:Loader = new Loader();
var image:URLRequest = new URLRequest("btn_A.png");
public function TextWithImage()
{
var TextField1:TextField = new TextField;
var myText1:String = "TEXT FIELD 1";
var BtnMovieClip:MovieClip = new MovieClip();
var btnPadding = 5;
addChild(BtnMovieClip); //add new MC to stage
btnAImage.load(image);
BtnMovieClip.addChild(btnAImage); // no error gets thrown. I am trying to add the btnAImage inside of my BtnMovieClip.
btnAImage.x = btnPadding; //I am able to reference the btnAImage without referencing the BtnMovieClip object.
btnAImage.y = btnPadding;
var screenW = stage.stageWidth;
TextField1.height = 40;
TextField1.width = 250;
var textPadding = 5;
var TextField1_fontFormat:TextFormat = new TextFormat ;
TextField1_fontFormat.size = 40;
TextField1_fontFormat.font = "TestFont";
TextField1.defaultTextFormat = TextField1_fontFormat;
BtnMovieClip.addChild(TextField1); // no error gets thrown. I am trying to add the text field inside of my BtnMovieClip.
TextField1.text = myText1;
TextField1.x = (btnAImage.width + textPadding);
TextField1.y = textPadding;
}
I wasn't preloading my image so here's how I fixed it. Thank you to Organis for the help!!!
public var btnAImage:Loader;
private function Question8_Answer()
{
trace("Question8_Answer() was called");
btnAImage = new Loader();
btnAImage.load(new URLRequest("btn_A.png"));
btnAImage.contentLoaderInfo.addEventListener(Event.COMPLETE, TextWithImage);
}
public function TextWithImage()
{
var TextField1:TextField = new TextField;
var myText1:String = "TEXT FIELD 1";
var BtnContainer:Sprite = new Sprite();
var btnPadding = 5;
addChild(BtnMovieClip);
BtnMovieClip.addChild(btnAImage);
btnAImage.x = btnPadding;
btnAImage.y = btnPadding;
var screenW = stage.stageWidth;
TextField1.height = 40;
TextField1.width = 250;
var textPadding = 5;
var TextField1_fontFormat:TextFormat = new TextFormat ;
TextField1_fontFormat.size = 40;
TextField1_fontFormat.font = "TestFont";
TextField1.defaultTextFormat = TextField1_fontFormat;
BtnMovieClip.addChild(TextField1); // no error gets thrown. I am trying to add the text field inside of my BtnMovieClip.
TextField1.text = myText1;
TextField1.x = (btnAImage.width + textPadding);
TextField1.y = textPadding;
BtnContainer.width = 300;
}
I am new here and a complete noob when it comes to as3. Somehow I have managed to put this together with some help from different places. And now I turn to you guys :)
I need to put smoothing on my images and thumbs that Im loading from an XML file. I have tried a lot of things but can't get any of it to work and I get this error:
Scene 1, Layer 'as3', Frame 1, Line 27 1120: Access of undefined property e. -> So I know var bitmapContent:Bitmap = Bitmap( e.target.content ); is the problem. but I have no idea what to use instead of e. I
this i what I have so far:
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.None;
import flash.display.Bitmap;
// Loads the first image//
var i =new Loader();
i.load(new URLRequest("images/1.jpg"));
mainLoader.addChild(i)
//Loads the XML file//
var picsXML:XML;
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE , xmlLoaded);
xmlLoader.load(new URLRequest("imagelist.xml"));
//Loads images into thumbs//
function xmlLoaded(event:Event):void{
picsXML = new XML(xmlLoader.data);
//trace(picsXML);
var bitmapContent:Bitmap = Bitmap( e.target.content );
bitmapContent.smoothing = true;
var thumbLoader:UILoader;
for (var i:uint=0; i<picsXML.image.length(); i++)
{
thumbLoader=UILoader(getChildByName("thumb"+i));
thumbLoader.load(new URLRequest("thumbs/"+picsXML.image[i].#file));
thumbLoader.buttonMode = true;
thumbLoader.addEventListener(MouseEvent.CLICK, thumbClicked);
thumbLoader.addEventListener(MouseEvent.CLICK, tester);
}
}
//Loads large image when thumb is clicked//
function thumbClicked(event:MouseEvent){
//var bitmapImage:Bitmap = event.target.content;
//bitmapImage.smoothing = true;
var thumbName:String = event.currentTarget.name;
var thumbIndex:uint = uint(thumbName.substr(5));
var fullPath:String = "images/"+picsXML.image[thumbIndex].#file;
mainLoader.load(new URLRequest(fullPath));
var myTween:Tween = new Tween(mainLoader,"alpha", None.easeNone, .3,1,18,false);
}
//Removes the first image when thumbs is clicked//
function tester(event:MouseEvent){
if (mainLoader.contains(i)) {
trace("hej")
mainLoader.removeChild(i);
}
}
If i get your code true problem is here: u import an external xml file which is probably contain your url's and name of pic's. U can't turn ur xml file into a bitmap.
If u want smoothing on your pictures u need to it after load ur pics or thumb's.
Probably ur problem will fix like this :) Hope this will help
Functions with arguments work like this: function Name ( input arg Name : input arg Type )
Firstly, your function xmlLoaded(event:Event) cannot have an input called event
but then you try to do a Bitmap( e.target.content ); so for that bitmap line to work you'd have to change your input name to e like so... xmlLoaded( e : Event );
Secondly, var bitmapContent:Bitmap = Bitmap( e.target.content ); is incorrect.
This is more correct var bitmapContent:Bitmap = img_Bytes_Loader.content as Bitmap; set a Loader's content as Bitmap not XML content (text) as Bitmap (pixels).
Anyways assuming your XML file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Items>
<mp3>
<url> track1.mp3 </url>
<image> image1.jpg </image>
</mp3>
<mp3>
<url> track2.mp3 </url>
<image> image2.jpg </image>
</mp3>
</Items>
Then your code should look something like this below :
var imgLoader_XML : URLRequest;
var picLoader : Loader = new Loader();
function xmlLoaded(event:Event):void
{
picsXML = new XML(xmlLoader.data);
//trace(picsXML);
imgLoader_XML = new URLRequest( picsXML.mp3[ index ].image ); //[index] could be replaced with [i] if FOR loop
picLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, picloadComplete);
picLoader.load (imgLoader_2);
}
public function picloadComplete(evt:Event)
{
yourContainer.addChild(picLoader);
yourContainer.width = 100;
yourContainer.height = 100;
yourContainer.alpha = 1;
}
Thanks for the inputs guys. It is greatly appreciated.
I figured it out. You were right, of course I can't put smoothing on the UILoader, so I had to target the content of the UILoader and run thumbLoader.addEventListener(Event.COMPLETE, smoothing); each time an image is importet.
Here is the entire working code (maybe it can help someone else :) :
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.None;
import flash.display.Bitmap;
import flash.display.Loader;
// Loads the first image//
var i =new Loader();
i.load(new URLRequest("images/1.jpg"));
mainLoader.addChild(i)
//Loads the XML file//
var picsXML:XML;
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE , xmlLoaded);
xmlLoader.load(new URLRequest("imagelist.xml"));
//Loads images into thumbs//
function xmlLoaded(event:Event):void{
picsXML = new XML(xmlLoader.data);
var thumbLoader :UILoader = new UILoader();
for (var i:uint=0; i<picsXML.image.length(); i++)
{
thumbLoader=UILoader(getChildByName("thumb"+i));
thumbLoader.load(new URLRequest("thumbs/"+picsXML.image[i].#file));
thumbLoader.buttonMode = true;
thumbLoader.addEventListener(MouseEvent.CLICK, thumbClicked);
thumbLoader.addEventListener(MouseEvent.CLICK, tester);
thumbLoader.addEventListener(Event.COMPLETE, smoothing);
}
}
function smoothing(e:Event):void{
if(e.currentTarget.content is Bitmap)
{
Bitmap(e.currentTarget.content).smoothing = true;
}
}
//Loads large image when thumb is clicked//
function thumbClicked(event:MouseEvent){
var thumbName:String = event.currentTarget.name;
var thumbIndex:uint = uint(thumbName.substr(5));
var fullPath:String = "images/"+picsXML.image[thumbIndex].#file;
mainLoader.load(new URLRequest(fullPath));
mainLoader.addEventListener(Event.COMPLETE, smoothing);
var myTween:Tween = new Tween(mainLoader,"alpha", None.easeNone, .3,1,18,false);
}
//Removes the first image when thumbs is clicked//
function tester(event:MouseEvent){
if (mainLoader.contains(i)) {
trace("hej")
mainLoader.removeChild(i);
}
}
I have code to create a live screenshot of the stage in my swf.
After that it saves as a jpeg. All good.
Only, I don't need the whole stage, I only need a cutout:
x,y: 357,341
widt,height: 319,483
My code looks like this..
Where and how do I insert the copypixels function?
(I'm a Flash novice, so go easy on me :-)
function mouseReleaseSave(event:MouseEvent):void {
import com.adobe.images.JPGEncoder;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequestHeader;
import flash.net.URLRequest;
var jpgSource:BitmapData = new BitmapData(this.stage.stageWidth, this.stage.stageHeight);
jpgSource.draw(this.stage);
var jpgEncoder:JPGEncoder = new JPGEncoder(70);
var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);
//set the request's header,method and data
var header:URLRequestHeader = new URLRequestHeader("Content-type","application/octet-stream");
var loader:URLLoader = new URLLoader();
//sends jpg bytes to saveJPG.php script
var myRequest:URLRequest = new URLRequest("saveJPG.php");
myRequest.requestHeaders.push(header);
myRequest.method = URLRequestMethod.POST;
myRequest.data = jpgStream;
loader.load(myRequest);
//fire complete event;
loader.addEventListener(Event.COMPLETE,saved);
function saved(e:Event){
//trace the image file name
trace(loader.data);
}
}
This should help:
var subArea:Rectangle = new Rectangle(0,0, 319,483 );
var newBmp:Bitmap = new BitmapData( 319,483 );
var cutoutBmp:Bitmap = new Bitmap( newBmp, PixelSnapping.ALWAYS, true );
cutoutBmp.bitmapData.draw( jpgSource, new Matrix(1, 0, 0, 1, -357, -341) , null, null, subArea, true );
Noob to As3 Bitmap stuff...
when i try to doing the following code it fails
bmd.setPixels(bmd.rect, decodeValue);
and the error message is:
Error: Error #2030: End of file was encountered.
The situation is i have store the image as binary into the database by convert the byteArray and now i would like to retrieve it and convert back to image.
Just to clear this up ByteArray Need to Place into Bitmap and then you can add to the movie Clip right?
import flash.display.Loader;
import flash.net.URLRequest;
import flash.display.Bitmap;
import flash.display.BitmapData;
import com.dynamicflash.util.Base64;
var loader:Loader;
var req:URLRequest;
var orig_mc:MovieClip;
var copy_mc:MovieClip;
function loaderCompleteHandler(evt:Event) {
//swap data
var ldr:Loader = evt.currentTarget.loader as Loader;
var origImg:Bitmap = (ldr.content as Bitmap);
var origBmd:BitmapData = origImg.bitmapData;
trace(origImg.bitmapData);
trace(origImg.width);
trace(origImg.height);
//Convert image byteData into Base64 String
var byteArray:ByteArray = new ByteArray();
byteArray.writeObject(origBmd);
var encoded:String = Base64.encodeByteArray(byteArray);
trace("\nENCODED:\n" + encoded);
var decoded:ByteArray = Base64.decodeToByteArray(encoded);
trace("\nDECODED:\n" + decoded.toString());
// convert base64 string back into movieclip
var newBmd:BitmapData = new BitmapData(origImg.width,origImg.height,"true",0xFFFFFFFF);
newBmd.setPixels(origBmd.rect, decoded);**// THIS THROWS AN " Error #2030: End of file was encountered."**
var image:Bitmap = new Bitmap(newBmd, "auto", true);
copy_mc.addChild(image);
copy_mc.x = origImg.width;
}
loader = new Loader();
req = new URLRequest("C:\\Data\\cutcord.jpg");
loader.load(req);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
// movieclip to display original image
orig_mc = new MovieClip();
orig_mc.addChild(loader);
addChild(orig_mc);
// movieclip to display image copy
copy_mc = new MovieClip();
addChild(copy_mc);
Anyone can help would be very appreciated :)
try this code :
var rect:Rectangle = new Rectangle(0,0,img.widht,img.height);
var byteArray:ByteArray = bitmapData.getPixels(rect);
var encoded:String = Base64.encodeByteArray(byteArray);
var decoded:ByteArray = Base64.decodeToByteArray(encoded);
decoded.position = 0;
var newBmd:BitmapData = new BitmapData(rect.width,rect.height,true,0xFFFFFFFF);
newBmd.setPixels(rect, decoded);
var image:Bitmap = new Bitmap(newBmd, "auto", true);
addChild(image);
anyway , Your idea of store string in server isnt too good ... Why You dont send ByteArray , not String ?
You can also encode bitmapData to JPG or PNG , and then send bytes to php.
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.
I have the following code:
public function Application()
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
var urlRequest:URLRequest = new URLRequest("image/1.jpg");
loader.load(urlRequest);
addChild(loader);
}
private function completeHandler(e:Event):void{
loader.content.width = 800;
loader.content.scaleY = loader.content.scaleX;
piece = Math.round(loader.height/10);
drawBitmaps();
}
private function drawBitmaps():void{
var bmdata:BitmapData = new BitmapData(loader.width, piece, true, 0x000000);
bmdata.draw(loader);
var bitmap:Bitmap = new Bitmap(bmdata);
addChild(bitmap);
loader.visible = false;
}
the result is a bitmap wich contains a pice of the image. The height is 80. and it starts at the top of the image. But how can i tell the bitmapdata to start drawing the image from lets say 80pixels? so it draws a middle piece of the image? Because atm it allways draws from the top of the image.
You should use BitmapData::draw clipRect parameter.
Here is an example:
package {
import flash.geom.Rectangle;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
public class BitmapDataTest extends Sprite {
public function BitmapDataTest() {
var c:Sprite = new Sprite();
var g:Graphics;
g = c.graphics;
g.beginFill(0xFF0000);
g.drawCircle(30,30,30);
g.endFill();
addChild(c);
c.x = 10;
c.y = 10;
var bmdata:BitmapData = new BitmapData(60, 60, true, 0x000000);
bmdata.draw(c,null,null,null, new Rectangle(0,30,30,30));
var bitmap:Bitmap = new Bitmap(bmdata);
addChild(bitmap);
bitmap.x = 80;
bitmap.y = 10;
}
}
}
Please notice that the target bitmap data should have the same dimensions as source or this won't work. If you really have to cut it down you should use BitmapData::copyPixels method.
The easiest way would be to apply a mask, dynamically. Here is a good example: Actionscript 3 and dynamic masks
You can create a rectangle, the height you're looking for and position it appropriately.
Hope this helps.