I need to convert bitmapData grabbed from movie clip to jpeg or png. Is there some lib for that?
see this example in take portion that convert byte to image, i have given whole for your reference
package {
import encoding.JPGEncoder;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.events.Event
public class Converter extends Sprite {
[Embed(source = "image.jpg")]
private var image:Class
private const QUALITY:uint = 80;
public function Converter():void {
var bitmap:Bitmap = new image();
var bitmapData:BitmapData = bitmap.bitmapData;
//encode BitmapData to JPG
var encoder:JPGEncoder = new JPGEncoder(QUALITY);
var rawBytes:ByteArray = encoder.encode(bitmap.bitmapData);
//decode JPG ByteArray back to BitmapData
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, getBitmapData)
loader.loadBytes(rawBytes);
}
private function getBitmapData(e:Event):void {
var decodedBitmapData:BitmapData = Bitmap(e.target.content).bitmapData
trace(decodedBitmapData);
}
}
}
You can now use the native jpeg encoding built into Flash Player 11.3 and AIR 3.3.
var quality:int = 50;
var bounds:Rectangle = bitmapData.rect;
var result:ByteArray = bitmapData.encode(bounds, new JPEGEncoderOptions(50));
This requires -swf-version=16 be passed to the compiler.
This is not the simplest way, but depending on the dimensions of your image, may be worth a look. Jens Krause has compiled jpeglib with Alchemy, and it encodes much faster than as3corelib's version, or even Thibault Imbert's improved AS3 version:
http://www.websector.de/blog/2009/06/21/speed-up-jpeg-encoding-using-alchemy/
Related
I have a problem when i wanna save screenshot entire flash stage using ActionScript 3. when i click button that use function SimpanGbr it's works for saving image with name "NamaGambar" but without type of JPG image. How to save image with it's type. I use these codes:
stop();
import flash.events.MouseEvent;
import flash.system.fscommand;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import com.adobe.images.JPGEncoder;
stage.displayState = StageDisplayState.FULL_SCREEN;
exit.addEventListener(MouseEvent.CLICK,keluar);
function keluar(event:MouseEvent):void
{
fscommand("quit");
}
function SimpanGbr(e:MouseEvent):void {
var qImageData:BitmapData = new BitmapData(800, 600);
qImageData.draw(stage);
var qEncoder:JPGEncoder = new JPGEncoder(100);
var qBytes:ByteArray = qEncoder.encode(qImageData);
var qFile:FileReference = new FileReference();
var nama:String="NamaGambar";
qFile.save(qBytes, nama+".jpg");
}
You can do so using this library.
After downloading copy the source files (the com folder) on to your Class path or your application root directory. Apart from the JPEGEncoder, this library is packaged with a lot of other classes related to Hasing, Text, Date etc.
This is how we save an image from a flash movie to a local machine.
1) Create a BitmapData object out of the MovieClip or the Loader.
2) Encode the BitmapData using the JPEGEncoder and form a ByteArray.
3) Use FileReference.save() to download the image on to the User machine.
See an example:
Create a blank Flash movie and name it as “ImageSave.fla”. In the same folder create “ImageSave.as” file and copy the below code in to it. You need the “com” folder copied from the as3corelib to this folder. I have a button on the stage named “save_mc” which triggers the saveImage function.
package {
import flash.display.MovieClip;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.utils.ByteArray;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLRequest;
import com.adobe.images.JPGEncoder;
public class ImageSave extends MovieClip {
private var imgFile:URLRequest;
private var img:MovieClip;
private var imgLoader:Loader;
private var file:FileReference;
public function ImageSave() {
imgFile = new URLRequest("coffee.jpg"); //change it to your image path
imgLoader = new Loader();
imgLoader.load(imgFile);
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
save_mc.addEventListener(MouseEvent.CLICK, saveImage);
}
private function onLoaded(evt:Event):void {
imgLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
imgLoader.cacheAsBitmap = true;
addChild(imgLoader);
}
function saveImage(e:MouseEvent):void {
var myBitmapData:BitmapData = new BitmapData(imgLoader.width, imgLoader.height);
myBitmapData.draw(imgLoader);
var jpgEncoder:JPGEncoder = new JPGEncoder(80);
var imgByteData:ByteArray = jpgEncoder.encode(myBitmapData);
file = new FileReference();
file.browse(new Array(new FileFilter("Images (*.jpg, *.jpeg)", "*.jpg;*.jpeg")));
file.save(imgByteData, "test.jpg");
}
}
}
For your convenience you can download a working copy of this sample here.
I'm doing a project in AS3 (no external libraries or Flex) and I need to embed an explosion animation over a tile when it gets destroyed. I have a small explosion animation but I don't know how I can get it to play at a specific location. Is there a way to do this? I've tried embedding it like so:
[Embed(source="../assets/64x48.swf", mimeType="application/octet-stream")] private var Explosion:Class
var explosion:MovieClip;
explosion = new Explosion();
explosion.play();
but this doesn't seem to do anything. If not an SWF, I also have a sprite sheet of an explosion I could use, but I'm not sure how to animate a sprite without using an external library.
Approach within your swf Movieclip you want to play, you must perform the following. swf convert to bytearray after, it must be restored.
EDIT
I checked your swf file. however, your swf file contents not MovieClip, but AVM1Movie file. so It is quite difficult to directly embedded. because AVM1Movie file convert to MovieClip Algorithm. but don't worry. using a ForcibileLoader easily available.
download a ForcibileLoader
original ForcibileLoader here
refer a following code. I tested great work.
package
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.utils.getTimer;
import org.libspark.utils.ForcibleLoader;
public class TestProject2 extends Sprite
{
private var loader:Loader = new Loader();
private var mc:MovieClip;
public function TestProjec2t()
{
var fLoader:ForcibleLoader = new ForcibleLoader(loader);
fLoader.load(new URLRequest("../asset/64x48.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSwfLoaded);
this.addChild(loader);
}
private function onSwfLoaded(e:Event):void
{
trace(e.currentTarget.content);
mc = e.currentTarget.content as MovieClip;
mc.x = Math.random() * stage.stageWidth;
mc.y = Math.random() * stage.stageHeight;
mc.gotoAndPlay(1);
}
}
}
I've completely run out of ideas on this. It follows, and is part of my previous question:
embedding a font in a swf using as3
I just don't seem to be able to get the flash.text.engine to use my embedded font. NB the font has to be loaded into the application (as embedded in swf) after the user has chosen the two languages (for translation to and from). There seems to be a little info implying that it is now necessary to use the fontswf application which is in the sdk. I have tried this and produced loadable swf files but I can't find any info on how these are then loaded (i.e. the getDefinition and registerFont bits below don't work as there are no classes in these swf) and applied to text.engine objects. The source for the embedding is in my answer to my question above. This is a test as3 which demonstrates how it doesn't work!
package
{
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.text.engine.ElementFormat;
import flash.text.engine.FontDescription;
import flash.text.engine.TextBlock;
import flash.text.engine.TextLine;
import flash.text.engine.TextElement;
import flash.net.URLRequest;
import flash.text.Font;
public class Main extends Sprite
{
private var loader:Loader;
private var tl:TextLine;
public function Main():void
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,fontLoaded);
loader.load(new URLRequest("EnglishF.swf"));
}
private function fontLoaded(evt:Event):void {
var FontClass:Class
FontClass = evt.target.applicationDomain.getDefinition("EnglishF") as Class;
try {
Font.registerFont(FontClass.myFont);
trace("successfully loaded " + FontClass);
// gives 'successfully loaded EnglishF'
} catch (err:Error) {}
var fontList:Array = Font.enumerateFonts();
for (var i:int = 0; i < fontList.length; i++) {
trace(fontList[i].fontName, fontList[i].fontType);
// gives 'EnglishF embeddedCFF'
}
var block:TextBlock = new TextBlock();
var font:FontDescription = new FontDescription("EnglishF");
var formt:ElementFormat = new ElementFormat(font, 30);
trace(FontDescription.isFontCompatible("EnglishF","normal","normal"), formt.fontDescription.fontName);
// gives 'true EnglishF'
formt.color = 0x882233;
var span:TextElement = new TextElement("Hello World. This is certainly NOT in the Font provided!", formt);
block.content = span;
tl = block.createTextLine();
tl.x = 10;
tl.y = tl.ascent + 10;
addChild(tl);
}
}
}
Am I doing anything wrong, or is this impossible?
Hopefully this will help. Under this line:
var font:FontDescription = new FontDescription("EnglishF");
add the following line:
font.fontLookup = FontLookup.EMBEDDED_CFF;
This will let the text framework know that you're using a CFF font (used in the new text framework), instead of a regular embedded font (used in TextFields).
Hope this helps.
Jordan
I am working on a project, where I have to make an annotation video player!
Basically, I followed this tutorial[1] where the author presents how to draw(in this case just a rectangle) on the own web camera, using Flex.
Everything went great, but now I want to add a listener to get a snapshot of the image(what I draw + the web camera image) and then save it on my computer.
I have created the listener, but the problem is that this listener saves only the image from the web camera without my drawing(even though I added that draw to the camera).
private function save():void {
var bitmapData:BitmapData = new BitmapData(videoDisplay.width,videoDisplay.height);
bitmapData.draw(videoDisplay);
var ba:ByteArray = (new PNGEncoder()).encode(bitmapData);
(new FileReference()).save(ba, "doodle.png");
}
I don't have experience at all with Flex/Flash so maybe I did smth wrong.
Can you please help me?
[1]http://narinderkumar.wordpress.com/2012/02/16/drawing-on-live-video-in-flex/
this example works fine - i dont see the problem in that codesnippet of yours but maybe you are just drawing vis graphics on the video, in thatcase the graphics layer is behind the camera... hope hat helps ;)
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Camera;
import flash.media.Video;
public class cameratest extends Sprite
{
private var holder:Sprite;
private var layover:Sprite;
private var display:Sprite;
public function cameratest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var cam:Camera = Camera.getCamera();
var video:Video =new Video(cam.width, cam.height);
video.attachCamera(cam);
//holder hollds the video and on top the layover to draw on
holder = new Sprite();
stage.addChild(holder);
holder.addChild(video);
//layover to draw on
layover = new Sprite();
holder.addChild(layover);
//will show the snapshot
display = new Sprite();
display.x= 350;
stage.addChild(display);
//listener for onclick do snapshot
stage.addEventListener(MouseEvent.CLICK, drawAndSave);
}
private function drawAndSave(E:Event=null):void{
layover.graphics.beginFill(0xff0000,1);
layover.graphics.drawCircle(10,10,10);
var bmd:BitmapData=new BitmapData(holder.width,holder.height);
bmd.draw(holder);
var bmp:Bitmap = new Bitmap(bmd,'auto',true);
display.addChild(bmp);
}
}
}
I am using Flash Text Engine's TextBlock & TextLine to display text. However, I found that some font make TextLine calculate height incorrectly. Here is my sample code:
package users
{
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.engine.ElementFormat;
import flash.text.engine.FontDescription;
import flash.text.engine.FontLookup;
import flash.text.engine.FontPosture;
import flash.text.engine.FontWeight;
import flash.text.engine.RenderingMode;
import flash.text.engine.TextBaseline;
import flash.text.engine.TextBlock;
import flash.text.engine.TextElement;
import flash.text.engine.TextLine;
public class TestTextSize extends Sprite
{
private var textBlock:TextBlock = null;
private var textElement:TextElement = null;
private var _textField:TextField;
private var _textFormat:TextFormat;
private var elementFormat:ElementFormat;
private var _textLine:TextLine;
[Embed(source="assets/fonts/SWANSE__.TTF", fontFamily="Swansea", mimeType="application/x-font", embedAsCFF="true")]
private const Swansea:Class;
public function TestTextSize()
{
super();
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
stage.scaleMode = StageScaleMode.NO_SCALE;
var fontDescription:FontDescription = new FontDescription("Swansea"
, FontWeight.NORMAL, FontPosture.NORMAL, FontLookup.EMBEDDED_CFF, RenderingMode.CFF);
elementFormat = new ElementFormat();
elementFormat.fontDescription = fontDescription;
elementFormat.fontSize = 114.5;
elementFormat.color = 0x990000;
textElement = new TextElement("This is some text", elementFormat);
textBlock = new TextBlock(textElement);
textBlock.baselineZero = TextBaseline.ASCENT;
_textLine = textBlock.createTextLine(null, 1000,0,true);
_textLine.y = 0;
addChild(_textLine);
trace(_textLine.height);
trace(_textLine.textHeight);
trace(_textLine.totalHeight);
trace(_textLine.totalAscent);
trace(_textLine.totalDescent);
var rect:Rectangle = _textLine.getBounds(this);
trace(rect.y, rect.height);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0x004400);
sprite.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
sprite.graphics.endFill();
sprite.alpha = 0.3;
sprite.y = 0;
addChild(sprite);
}
}
}
The font I'm using is Swansea (http://www.fontspace.com/roger-white/swansea) standard normal font.
From the code, I extract TextLine's height by using getBounds, and use that height to draw rectangle. The rectangle appears to has height shorter than the actual text, means that getBounds can't get correct actual text height.
The result from running the code looks like this:
The console give the following result:
57.6
57.59326171875
57.59326171875
0
57.59326171875
0 57.6
which means TextLine.textHeight, height, totalHeight, and result from getBounds give the same value, roughly 57.6 pixel.
So, my question is, how can I get the actual text height?
Please don't tell me not to use Swansea. So far, I have tried 5-6 different fonts and only Swansea give me this problem. But, how do I know that this problem will not happen again? At least, if there is a way to distinguish font that give this problem and font that won't, that would be highly appreciated.
I have found that if I comment out the line
textBlock.baselineZero = TextBaseline.ASCENT;
then the totalHeight and totalAscent property will return 83.81396484375.
Maybe you could also try to re-package the font with a font editor.