AS3 webcam resolution/size issue - actionscript-3

I do not really know much in regard to Flash or Action Scripts but I have been having a bit of trouble with AS3 and webcams. I have a script that connects to a webcam and then sends its output to a php script that saves the captured image. This works all except for one problem. It seems that the maximum resolution allowed for the actual Camera object is 320x240. I went to the extreme of hooking a Canon 60D up as a webcam because I have a normal webcam that is supposed to have max resolution of 1280x720 and all I can get is a 320x240 image from it. What I have found so far is the max I can get out of the Canon is also 320x240. Maybe I have been looking at this to long but I am stumped. Below is a sample of the action script where videoCapture should be 1024x768. What happens instead is a 1024x768 image is created with a black background and in the top left is a 320x240 image from videoCapture. I could obviously resize this but that would defeat the purpose being poor quality. Is there something I am missing here or maybe some limitation of Flash even?
// adds event listener to the stage for keydown events.
stage.addEventListener(KeyboardEvent.KEY_DOWN, detectEnterKey);
import flash.display.Bitmap;
import flash.display.BitmapData;
import com.adobe.images.JPGEncoder;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
var bandwidth:int = 0;
var quality:int = 100;
var cam:Camera = Camera.getCamera();
var videoCapture:Video = new Video();
var previewPortData:BitmapData = new BitmapData(1024, 768, true, 0x00000000);
var previewPort:Bitmap = new Bitmap(previewPortData);
function onCameraStatus(evt):void {
if (evt.code == "Camera.Muted") {
Security.showSettings(SecurityPanel.CAMERA);
}
}
// detects the keycode looking for enter key pressed.
function detectEnterKey(event:KeyboardEvent):void {
//trace("keycode: "+event.keyCode);
if (event.keyCode == Keyboard.ENTER) {
previewPortData.draw(videoCapture);
var myEncoder:JPGEncoder = new JPGEncoder(100);
var byteArray:ByteArray = myEncoder.encode(previewPortData);
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var saveJPG:URLRequest = new URLRequest("save.php");
saveJPG.requestHeaders.push(header);
saveJPG.method = URLRequestMethod.POST;
saveJPG.data = byteArray;
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, sendComplete);
urlLoader.load(saveJPG);
function sendComplete(event:Event):void {
trace("compete");
}
}
}
if (cam == null) {
Security.showSettings(SecurityPanel.CAMERA);
} else {
cam.addEventListener(StatusEvent.STATUS, onCameraStatus)
cam.setQuality(bandwidth, quality);
cam.setMode(1024, 768, 30, false);
videoCapture.attachCamera(cam);
videoCapture.width = 1024;
videoCapture.height = 768;
addChild(videoCapture);
previewPort.x = 430;
previewPort.y = 50;
addChild(previewPort);
}

I also just had this problem. Solved it by including the width and height parameters when creating the Video object instead of setting them afterwards via Video.height and Video.width. Once i did that, all bitmapData taken from that video was correctly sized.
This is how i originally created the video that did not work (looked fine, but resulted in incorrectly sized bitmaps):
var vid = new Video();
vid.width = 640;
vid.height = 480;
...
This worked (bitmaps from this video were correctly sized):
var vid = new Video(640, 480);
...
Would love to know why the first way doesn't work. Maybe that's the bug mentioned above. (I didn't have access to that site so couldn't see it.)

Sounds like this bug was never fixed: http://bugs.adobe.com/jira/browse/FP-2138

I had a similar issue. What worked for me was that I replaced:
previewPortData.draw(videoCapture);
With:
previewPortData.draw(stage);

Related

How to save a cropped image on stage and load into another swf with air

i have a problem. The main problem is in my apk , there are 3 swf file.
first swf file decides who can be the second swf between swfA and swfB.
for example swfA is chosen. swfA takes a screenshot of an cropped area and load main swf again. i need to load this screenshot into main swf right now. but it is not visible on the screen. it doesnt load. where is the point that i miss ?
save an image code is : (class main for swf1)
public function takeScreenshot():void
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.ByteArray;
import flash.net.FileReference;
import PNGEnc;
var myCroppedImage:Bitmap = crop(232, 121, 188, 570, this);
var d:BitmapData = new BitmapData(myCroppedImage.width, myCroppedImage.height);
d.draw(myCroppedImage);
var bild:ByteArray = PNGEnc.encode(d);
var newImage:File = File.applicationDirectory.resolvePath("app:/yeniResim.png");
var fileStream:FileStream = new FileStream();
fileStream.open(newImage , FileMode.UPDATE);
fileStream.writeBytes(bild);
fileStream.close();
//isimGoster.visible = false;
}
public function crop( _x:Number, _y:Number, _width:Number, _height:Number, displayObject:DisplayObject = null):Bitmap
{
var cropArea:Rectangle = new Rectangle( 0, 0, _width, _height );
var croppedBitmap:Bitmap = new Bitmap( new BitmapData( _width, _height ), PixelSnapping.ALWAYS, true );
croppedBitmap.bitmapData.draw( (displayObject!=null) ? displayObject : stage, new Matrix(1, 0, 0, 1, -_x, -_y) , null, null, cropArea, true );
return croppedBitmap;
}
load an image into another swf : (class main for swf 2)
public function frame4():void {
stop();
resim = new Loader();
var meRequest:URLRequest = new URLRequest('app:/yeniResim.png');
resim.load(meRequest);
var mce:MovieClip = resim.content as MovieClip;
mce.x = 480;
mce.y = 320;
}
It looks like you're not waiting for the Loader to finish loading the file before you access its content. For example, it is likely that "content" in this line below does not contain the loaded image at the time you try and use it:
var mce:MovieClip = resim.content as MovieClip;
It's been a long time since I did anything in Flash, so this code may not be quite right. But I'm very certain you need to do something like this:
var mce:MovieClip;
resim = new Loader();
resim.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
var meRequest:URLRequest = new URLRequest('app:/yeniResim.png');
resim.load(meRequest);
function imgLoaded(event:Event):void
{
mce = resim.content as MovieClip;
mce.x = 480;
mce.y = 320;
}
The other alternative is not waiting for the COMPLETE event and just adding the Loader to the stage. However, since you want to cast Loader.content into a MovieClip you need to wait for the content to be loaded. Check this example for more details.
It's also good to attach an event listener to handle any failures. Loader.contentLoaderInfo is a LoaderInfo object, you can see the other events that it dispatches in case you need to trouble shoot further.

Loading images using the URLRequest

recently started to learn ActionScript 3 and already have questions.
question remains the same: I'm uploading a picture using the object Loader.load (URLRequest). Loaded and displayed a picture normally. But it is impossible to read the values of attributes of the image height and width, instead issued zero. That is, do this:
var loader:Loader=new Loader();
var urlR:URLRequest=new URLRequest("Image.jpg");
public function main()
{
loader.load(urlR);
var h:Number = loader.height;// here instead of the width of the image of h is set to 0
// And if you do like this:
DrawText(loader.height.toString(10), 50, 50); // Function which draws the text as defined below
// 256 is displayed, as necessary
}
private function DrawText(text:String, x:int, y:int):void
{
var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.background = true;
txt.border = true;
txt.backgroundColor = 0xff000000;
var tFor:TextFormat = new TextFormat();
tFor.font = "Charlemagne Std";
tFor.color = 0xff00ff00;
tFor.size = 20;
txt.x = x;
txt.y = y;
txt.text = text;
txt.setTextFormat(tFor);
addChild(txt);
}
Maybe attribute values must be obtained through the special features, but in the book K.Muka "ActionScript 3 for fash" says that it is necessary to do so. Please help me to solve this. Thanks in advance.
Well it's simple.
Flash is focused on the Internet, hence such problems.
If you wrote loader.load (urlR); it does not mean loaded. Accordingly, prior to the event confirming the end of loading, in loadare Null
if, instead of certain functions would be more code that would perhaps tripped your approach.
Yeah plus still highly dependent on the size of the file that you read.
Well, in general it all lyrics. Listen event on loader.contentLoaderInfo.addEventListener (Event.INIT, _onEvent), onEvent and read properties.
You need to wait for your image to load to be able to get values out of it.
Attach an eventListener to your URLLoader.
var urlR:URLRequest = new URLRequest("Image.jpg");
loader.load(urlR);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
function loader_complete(e:Event): void {
// Here you can get the height and width values etc.
var target_mc:Loader = evt.currentTarget.loader as Loader;
// target_mc.height , target_mc.width
}
Loader

Flash AS3 animation not running in IE9

I've got five Flash animations, that use AS3 computeSpectrum to create video animations for some of my songs.
Tested in Chrome, Firefox, Opera, and Safari just fine. Tested in IE7 and IE8 just fine. Tested in IE9, the flash player opens, but the music doesn't play, and the animations don't even start. This ONLY occurs in IE9.
Web page here: http://seanmurphy.co.cc/index4.html
The animations are under the music tab (bottom tab, main screen).
Does anyone have a line on what the heck is going on? I've made sure the Flash player is up-to-date (like I said, actually uninstalled IE9, back to IE8 and worked fine). I've made sure the linked mp3 files are in both the root folder and the attached audio folder (just in case). I've researched this all over, but no one seems to have this same problem.
Flash AS3 code below:
var url:String = "SubwayGirl.mp3";
var request:URLRequest = new URLRequest(url);
import flash.filters.*;
import fl.motion.Color;
var myBlur:BlurFilter = new BlurFilter();
myBlur.quality = 10;
myBlur.blurX = 0;
myBlur.blurY = 6;
var s:Sound = new Sound();
s.addEventListener(Event.COMPLETE, completeHandler);
s.load(request);
var song:SoundChannel = s.play();
song.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
var ba:ByteArray = new ByteArray();
var gr:Sprite = new Sprite();
gr.x = 150;
gr.y = 575;
addChild(gr);
var time:Timer = new Timer(.0001);
time.addEventListener(TimerEvent.TIMER, timerHandler);
time.start();
function completeHandler(event:Event):void {
//event.target.play();
};
function randomNumber(low:Number=0, high:Number=1):Number
{
return Math.floor(Math.random() * (1+high-low)) + low;
}
function soundCompleteHandler(event:Event):void {
time.stop();
};
function timerHandler(event:TimerEvent):void {
SoundMixer.computeSpectrum(ba, true);
var i:int;
gr.graphics.clear();
gr.graphics.lineStyle(1, 0xffffff);
myBlur.blurX = randomNumber(1, 5);
myBlur.blurY = randomNumber(1, 25);
myBlur.quality = randomNumber(1, 100);
gr.filters = [myBlur];
gr.graphics.beginFill(0xffffff);
gr.graphics.moveTo(10, 5);
var w:uint = 20;
for (i=0; i<500; i+=w) {
var t:Number = ba.readFloat();
var n:Number = (t * 100);
gr.graphics.drawCircle(w, -i, -n);
var yy = i * (t+210);
var place = yy.toString(16).toUpperCase();
while(place.length < 6) {
place = place+"0";
}
place = "0x" + place;
var myColor:ColorTransform = gr.transform.colorTransform;
myColor.color = 0xC941D0;
gr.transform.colorTransform = myColor;
};
};
Anyone with a hint on this? I've spent hours researching this with no resolution.
Any further info needed will be ASAPed over. Thanks.
EDIT: Okay, here's the scoop: I've got Flash animations playing at seanmurphy.co.cc/soundTest1.html in IE9. That is, they play if the browser cache is emptied, and you load the page once. If you reload the page, or go back to the page after visiting another page, the animations and music WON'T play, until you empty the cache again.
As well, I've copied the Flash object and embed codes over to a temporary index file at seanmurphy.co.cc/index6.html, but they won't play even with the browser cache emptied.
As you might think, this is driving me friggin' nuts! Does ANYONE have an explanation for the idiotic crap that IE is pulling here? I'd really really like to put this thing to bed. Thanks!
It may have something to do with the Security Sandbox violation:
SecurityError: Error #2121: Security sandbox violation:
SoundMixer.computeSpectrum: http://seanmurphy.co.cc/audio/IndianSummer-amped.swf
cannot access http://seanmurphy.co.cc/audio/SubwayGirl.swf.
This may be worked around by calling Security.allowDomain.
at flash.media::SoundMixer$/computeSpectrum()
at IndianSummer_fla::MainTimeline/timerHandler()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

Save original bitmapData from scaled video in AS3

I have a flash photo booth (web cam) application that I'm trying to wrap up but seem to be having issues trying to save a 640x480 image from a scaled down video window. The video seems to be scaling down fine but when I draw it to a bitmap it's shrinking the photo even more so I had to create a matrix scale of 2.0 to resize it back to 640x480 and I'm not sure if doing so is hurting the quality of the image. I don't want to use any resize hacks (especially up-scaling).
I'm new to AS3 so please forgive me.
import flash.display.Bitmap;
import flash.display.BitmapData;
import com.adobe.images.JPGEncoder;
var cam:Camera = Camera.getCamera();
cam.setQuality(0, 100);
cam.setMode(640,480,30,true); // setMode(videoWidth, videoHeight, video fps, favor area)
var video:Video = new Video();
video.attachCamera(cam);
video.x = 382;
video.y = 225;
video.width = 256;
video.height = 192;
addChild(video);
var bitmapData:BitmapData = new BitmapData(640,480);
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = 648;
bitmap.y = 225;
bitmap.width = 256;
bitmap.height = 192;
addChildAt(bitmap, 18);
photoCapture.buttonMode = true;
photoCapture.addEventListener(MouseEvent.CLICK,captureImage);
here is the dirty part...
function captureImage(e:MouseEvent):void {
var scale:Number=2.0;
var matrix:Matrix = new Matrix();
matrix.scale(scale, scale);
bitmapData.draw(video, matrix, null, null, null, true);
var jpgEncoder:JPGEncoder=new JPGEncoder(100);
var byteArray:ByteArray=jpgEncoder.encode(bitmapData);
var fileReference:FileReference=new FileReference();
fileReference.save(byteArray, ".jpg");
}
Basically I just want two small box's about 256x192 showing the video stream (640x480) and captured photo (640x480) and when I save it actually saves a 640x480 image.
var video:Video = new Video(640, 480);
This should prevent having to use a matrix. Video by default is 320x240.
First you create a video 256x192
then you create a bitmapData 640x480
then you shrink this bitmapdata (well, the bitmap actually) to 256x192
then you try to draw a small video into a large bitmap(data) - no wonder that you have to upscale
Create a BitmapData, Bitmap and Video in the same size and everything should be OK.
If you want the final image to be 640x480 you should create video, bitmap, bitmapdata in this size, then add the video to an empty MovieClip/Sprite (container) and scale container in order to fit it on the screen.
private var cam:Camera;
private var myVideo:Video;
private function attachCamera():void
{
cam = Camera.getCamera();
cam.setMode(8192,6144,30,true);
cam.setQuality(0,100);
myVideo = new Video(160,120);
//Flip preview on camera and result!
var flip:Matrix = new Matrix();
flip.scale(-1,1)
flip.translate(myVideo.width,0)
myVideo.transform.matrix = flip;
myVideo.attachCamera(cam);
videoDisplay.addChild(myVideo);
}
private function takePicture():void
{
var bd:BitmapData = new BitmapData(cam.width,cam.height);
//fill db with source bitmap!!!
cam.drawToBitmapData(bd)
//Then the bd contains the highest possible camera source!
// But videoDisplay show's small preview!
}

Stream an FLVPlayback through the internet

I have a video in flash in the size of 19 MB (5 minutes) and I want the user to see what that has been loaded so far, or even get an indication of what has been loaded - so he won't be stuck in a blank screen until the video loads.
The quality of the video is important so I won't resize it - but how can I:
stream it so the user can see what that has been loaded so far
give him an indication of how long he will need to wait until it loads.
My code looks something like this:
import fl.video.*;
var video = new FLVPlayback();
video.fullScreenTakeOver = false;
video.source = "MansfredLoop.f4v";
stage.addChild(video);
Where do I start?
import fl.video.*;
var totalBytes:int;
var loadedBytes:int;
var remainingBytes:int;
var myTimer:Timer = new Timer(100);
var video = new FLVPlayback();
video.fullScreenTakeOver = false;
video.source = "MansfredLoop.f4v";
stage.addChild(video);
myTimer.addEventListener("timer", timerHandler);
myTimer.start();
totalBytes = video.bytesLoaded;
function timerHandler(event:TimerEvent):void {
loadedBytes = video.bytesLoaded;
remainingBytes = totalBytes - loadedBytes;
}