How to scale BitmapData AS3? - actionscript-3

I am editing an air application for a client, and he wants the images that you import to be scaled to 650x650 when you save them by using the code below. I tried changing the values but when the image is exported some part is missing:
function menuItemClick1(event:Event):void{
var mat:Matrix = new Matrix();
mat.scale(2.0,2.0);
var bmpData:BitmapData = new BitmapData(this.template_mc.width * 2, this.template_mc.height * 2, false, 0xFFFFFF);
bmpData.draw(this.template_mc, mat);
var _bmp:Bitmap = new Bitmap(bmpData);
_bmp.smoothing = true;
//
imgBytes = PNGEncoder.encode(_bmp.bitmapData);
fs = new FileStream();
targetFile = File.desktopDirectory.resolvePath("icons/image.png");
targetFile.browseForSave("Save Your File");
targetFile.addEventListener(Event.SELECT, onSaveSelect);
}
I tried changing to this with no luck:
mat.scale(1.0,1.0);
var bmpData:BitmapData = new BitmapData(650,650, false, 0xFFFFFF);

Calculate matrix scale ratio this way:
var mat:Matrix = new Matrix();
var ratio:Number =Math.min(650/this.template_mc.width,650/this.template_mc.height);
mat.scale(ratio,ratio);
var bmpData:BitmapData = new BitmapData(650, 650, false, 0xFFFFFF);
bmpData.draw(this.template_mc, mat);

Related

Away3d transparent bitmap Sprite3d

I'm adding some circles to away3d as sprite3ds, but for some reason they all have white backgrounds that I can't seem to remove. Anyone know what I'm missing:
var hotspot:Hotspot = e.target as Hotspot;
var spBoard:Sprite = new Sprite();
spBoard.x = circleX;
spBoard.y = circleY;
var shCircle:Shape = new Shape();
shCircle.graphics.lineStyle(2,0x000000);
shCircle.graphics.drawCircle(0,0,circleR);
shCircle.x = 0;
shCircle.y = 0;
var shFill:Shape = new Shape();
shFill.graphics.lineStyle(1,0x000000);
shFill.graphics.moveTo(0,0);
shFill.graphics.lineTo(circleR,0);
shFill.x = 0;
shFill.y = 0;
var shAngle:Shape = new Shape();
var shArrow:Shape = new Shape();
shArrow.graphics.lineStyle();
shArrow.graphics.beginFill(0x000000);
shArrow.graphics.moveTo(angleR,1);
shArrow.graphics.lineTo(angleR-5,8);
shArrow.graphics.lineTo(angleR+5,8);
shArrow.graphics.lineTo(angleR,1);
shArrow.graphics.endFill();
spBoard.addChild(shFill);
spBoard.addChild(shAngle);
spBoard.addChild(shArrow);
spBoard.addChild(shCircle);
var hotspotTimer:MovieClip = new MovieClip();
hotspotTimer.addChild(spBoard);
var bounds:Rectangle = hotspotTimer.getBounds(hotspotTimer);
var bitmapData : BitmapData = new BitmapData(512, 512);
bitmapData.draw(hotspotTimer);
var bitmapPointsTexture:BitmapTexture = new BitmapTexture(bitmapData);
var _pointsMaterial:TextureMaterial = new TextureMaterial(bitmapPointsTexture);
var inworldHotspotTimer:Sprite3D = new Sprite3D(_pointsMaterial,bitmapData.width,bitmapData.height);
inworldHotspotTimer.x = hotspot.x;
inworldHotspotTimer.y = hotspot.y;
inworldHotspotTimer.z = hotspot.z;
scene.addChild(inworldHotspotTimer);
}
I've seen in blog posts such as this
http://www.allforthecode.co.uk/aftc/forum/user/modules/forum/article.php?index=6&subindex=4&aid=315
On how they do it, but they're using an older version with the BitmapMaterial removed.
Change the line that declares the bitmapdata to this:
var bitmapData : BitmapData = new BitmapData(512, 512, true, 0x00808080);
If you don't fill the bitmap with a color that has alpha of 0, you'll get the borders in the texture.

How can i set image size while encoding using jpeg encoder in flex

var dt : Date = new Date();
var jpg:JPEGEncoder= new JPEGEncoder;
var ba:ByteArray = jpg.encode(parentDocument.newBitmapData);
file.save(ba,'Screenshot at'+dt.time+'.jpg');
I have to save the image in different sizes
for eg : 800x600, 640x480 etc
You can just scale the bitmapData before encoding:
var bd800x600:BitmapData = new BitmapData(800, 600);
bd800x600.perlinNoise(10, 10, 8, 21, true, true);
var newW:int = 640;
var newH:int = 480;
var bd640x480:BitmapData = new BitmapData(newW, newH);
var mt:Matrix = new Matrix();
mt.scale(newW/bd800x600.width, newH/bd800x600.height);
bd640x480.draw(bd800x600, mt);
and than use your code to save the scaled bitmapdata.

how to set a bitmap as a mask

i want to apply a picture which contains transparent areas as a mask to a display object.
the mask only show the area which the mask has color.but in fact,the display object still show the whole area.so i convert bitmap to a vector image,that's solve the problem,but the convert method is horrible.
public static function createVectorImage(bd:BitmapData,colorKey:uint = 0):Shape{
if(bd==null){
return null;
}
var sh:Shape = new Shape();
var g:Graphics = sh.graphics;
g.beginBitmapFill(bd);
var beginPixel:int = -1;
var i:int,il:int,j:int,jl:int;
var value:uint;
for(i = 0,il=bd.height;i<il;i++){
for(j = 0,jl = bd.width;j<jl;j++){
value = bd.getPixel32(j,i);
if(value!=colorKey&&beginPixel==-1){
beginPixel = j;
}else if(value==colorKey&&beginPixel!=-1){
//draw rect
g.drawRect(beginPixel,i,j-beginPixel,1);
beginPixel = -1;
}
}
if(beginPixel!=-1){
g.drawRect(beginPixel,i,j-beginPixel,1);
beginPixel = -1
}
}
g.endFill();
return sh;
}
is there any way better than this?
You can convert your display object to a bitmap then apply a mask on it.
Convert you display object to a bitmap data:
var rect:Rectangle = displayObject.getRect();
var displayBD:BitmapData = new BitmapData(rect.width, rect.height, true, 0);
displayBD.draw(displayObject);
Apply the mask:
private static const ORIG:Point = new Point(0, 0);
private static function createBitmapDataWithMask(
baseBD:BitmapData, maskBD:BitmapData):BitmapData
{
var bitmapData:BitmapData;
bitmapData = new BitmapData(baseBD.width, baseBD.height, true, 0x000000);
bitmapData.copyPixels(baseBD, baseBD.rect, ORIG, maskBD, ORIG, true);
return bitmapData;
}
Display the bitmap data:
var bitmapData:BitmapData = createBitmapDataWithMask(displayBD, maskBD);
var bitmap:Bitmap = new Bitmap(bitmapData, "auto", true);
addChild(bitmap);
If you remove the bitmap from the stage, don't forget the free the bitmap data!
removeChild(bitmap);
bitmap.bitmapData.dispose();
bitmap = null;
Another option would be to use bitmap caching. It needs to be applied to the mask as well as the maskee:
var bd:BitmapData = new BitmapData(200, 200, true, 0x00000000);
bd.fillRect(new Rectangle(0, 0, 40, 40), 0xff000000);
var mask:Bitmap = new Bitmap(bd);
mask.cacheAsBitmap = true;
var maskee:Sprite = new Sprite();
maskee.cacheAsBitmap = true;
maskee.graphics.beginFill(0xff0000, 1);
maskee.graphics.drawRect(0, 0, 200, 200);
maskee.graphics.endFill();
maskee.mask = mask;
addChild(mask);
addChild(maskee);

AS3 copying masked bitmap onto another bitmap

I'm having a bit of a problem copying the masked only pixels from one bitmap onto another. Basically I'm masking bitmap A with bitmap B, which is working fine, but I'm unsure how to copy just the masked pixels onto Bitmap C which is the only one I want to keep.
//all this works fine
var _texture:Bitmap = new Bitmap(new Dirt_Bitmap);
var _mask:Bitmap = new Bitmap(new Mask_Bitmap);
var _planter:Bitmap = new Bitmap(new Planter_Bitmap);
_texture.cacheAsBitmap = _mask.cacheAsBitmap = true;
_texture.mask = _mask;
//This is where things get weird :[
var newBitmap:Bitmap = new Bitmap(new BitmapData(50, 50, true));
newBitmap.bitmapData.copyPixels(_texture.bitmapData, _texture.bitmapData.rect, new Point());
_planter.bitmapData.copyPixels(_newBitmap.bitmapData, _newBitmap.bitmapData.rect, new Point());
how would I go about just copying or drawing or maybe merg() just the masked texture so its copied over the planter graphic where the dirt should be? Any and all help will be greatly appreciated! :]
When you use copyPixels, you are actually copying the content of a bitmap without anything that's added by environment (no masking or transforms).
Use draw() instead.
Here's a sample:
var texture:Bitmap = new Bitmap(new BitmapData(200, 200, false, 0xFFFF0000));
var imageMask:Bitmap = new Bitmap(new BitmapData(200, 200, true, 0));
var rect:Rectangle = new Rectangle(0, 0, 10, 10);
imageMask.bitmapData.fillRect(rect, 0xFF000000);
rect.x = 50;
rect.y = 50;
imageMask.bitmapData.fillRect(rect, 0xFF000000);
texture.cacheAsBitmap = true;
imageMask.cacheAsBitmap = true;
texture.mask = imageMask;
addChild(imageMask);
addChild(texture);
var planter:Bitmap = new Bitmap(new BitmapData(200, 200, true, 0));
// that's it
planter.bitmapData.draw(texture);
addChild(planter);
planter.x = 100;

Trying to capture stage area using BitmapData

I am trying to grab part of stage area using BitmapData and copyPixels method:
bmd = new BitmapData(stage.stageWidth, stage.stageHeight);
bmdRect = new BitmapData(320, 240);
rectangle = new Rectangle(360, 20, 320, 240);
bmdRect.copyPixels(bmd, rectangle, new Point());
bmd.draw(bmp);
bmp = new Bitmap(bmdRect);
var myEncoder:JPGEncoder = new JPGEncoder(100);
var byteArray:ByteArray = myEncoder.encode(bmd);
The result i get is an empty .jpg I m pretty sure that the error is in the Bitmap procedure and not the saving one...
Finally used this solution to copy part of the stage
(I copied everything that is on stage from (360, 20) and after)
var bitmapdata:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
bitmapdata.draw(stage);
var bitmapDataA: BitmapData = new BitmapData(300, 250);
bitmapDataA.copyPixels(bitmapdata, new Rectangle(360, 20, 320, 240), new Point(0, 0));
var myEncoder:JPGEncoder = new JPGEncoder(90);
var byteArray:ByteArray = myEncoder.encode(bitmapDataA);
Can't you just call bmd.draw(stage)?
var stage_snapshot:BitmapData = new BitmapData(600, 120);
var myRectangle:Rectangle = new Rectangle(0, 0, 600, 120);
var myMatrix:Matrix = new Matrix();
var translateMatrix:Matrix = new Matrix();
translateMatrix.translate(-100, -225);
myMatrix.concat(translateMatrix);
stage_snapshot.draw(stage,myMatrix,null,null,myRectangle);
var encoded_jpg:JPGEncoder = new JPGEncoder(100);
var jpg_binary:ByteArray = new ByteArray();
jpg_binary = encoded_jpg.encode(stage_snapshot);