Dǝve Derıso

This here script does what everybody’s been looking for. A simple flash webcam app that uploads images from your webcam to the web. It also lets you download the image you just took.

Here’s a working demo.

Here’s the source files.

Here’s how it works:

  1. The flash code creates the camera and takes the picture as bitmapdata
  2. This bitmapdata is fed into a jpeg encoder (in the flash app)
  3. The encoded jpeg is then pushed out of flash into a php script on your server
  4. The php script saves a copy on the server and then pops up a download link

Here is the code:

AS3:

	package  {

		import fl.controls.Button;
		import fl.controls.TextArea;
		import flash.display.LoaderInfo;
		import flash.display.BitmapData;
		import flash.display.Bitmap;
		import flash.display.MovieClip;
		import flash.display.Stage;
		import flash.display.StageAlign;
	        import flash.display.StageScaleMode;	
		import flash.events.MouseEvent;
		import flash.events.StatusEvent;
		import flash.geom.Matrix;
		import flash.media.Camera;
		import flash.media.Video;
		import flash.net.navigateToURL;
		import flash.net.URLRequest;
		import flash.net.URLLoader;
	        import flash.net.URLRequestHeader;
	        import flash.net.URLRequestMethod;
		import flash.utils.ByteArray;
		import com.adobe.images.JPGEncoder;


		public class WebCamUploader extends MovieClip {

			// public Properties:
			public var spinner:Spinner;
			public var video:Video;
			public var camera:Camera;
			public var bitmap:Bitmap;
			public var bitmapData:BitmapData;
			public var snapShot:BitmapData;
			public var xVar:Number;
			public var yVar:Number;
			public var inventoryName:String;

			public function WebCamUploader() { 
				configUI();
			}

			public function configUI():void {
				stage.scaleMode = StageScaleMode.NO_SCALE;
				stage.align = StageAlign.TOP_LEFT;

				inventoryName_txt.text = "enter part # here";

				spinner = new Spinner();
				spinner.x = 214 - spinner.width >> 1;
				spinner.y = 255 - spinner.height - 40 >> 1;

				uploadPic.addEventListener(MouseEvent.MOUSE_UP, uploadPhoto, false, 0, true);
				deletePic.addEventListener(MouseEvent.MOUSE_UP, deletePhoto, false, 0, true);
				takePic.addEventListener(MouseEvent.MOUSE_UP, takeSnapShot, false, 0, true);

				connectCamera();
			}

			public function connectCamera():void {
				camera = Camera.getCamera();
				camera.setQuality(0, 100);
				camera.setMode(500, 500, 5, true);

				xVar = (500 - camera.width)/2;
				yVar = 26 + (500 - camera.width)/2;

				if (camera != null) {
	                video = new Video(camera.height, camera.width);
					video.attachCamera(camera);
					video.x = xVar;
					video.y = yVar;
					addChild(video);

					camera.addEventListener(StatusEvent.STATUS, onCameraStatus, false, 0, true);

					size_txt.text = "h: "+ camera.height + " w: " + camera.width + " fps: 5";
	            } else {
	                //handleError(false, "Error, You need a camera.");
	            }
			}

			public function onCameraStatus(p_event:StatusEvent):void {
				camera.removeEventListener(StatusEvent.STATUS, onCameraStatus);

				switch (p_event.code) {
					case "Camera.Muted":
						//handleError(false, "Error, Camera not found or denied. Unable to use Application. \nTo allow the Camera, reload the page.");
					case "Camera.Unmuted":
						// Camera accepted and Successfull;
						break;
				}
			}

			public function takeSnapShot(event:MouseEvent):void {

				snapShot = new BitmapData(video.width, video.height);
				snapShot.draw(video, new Matrix());
				bitmapData = snapShot;
				bitmap = new Bitmap(snapShot,"auto", true);

				bitmap.x = xVar;
				bitmap.y = yVar;

				addChild(bitmap);			
			}

			public function deletePhoto(event:MouseEvent):void {
				removeChild(bitmap);
			}

			public function uploadPhoto(event:MouseEvent):void {
				showSpinner(true);
				uploadPhotoPhp();
			}

			public function uploadPhotoPhp():void {

				var jpgEncoder:JPGEncoder = new JPGEncoder(85);
				var jpgStream:ByteArray = jpgEncoder.encode(bitmapData);
				var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");

				if (inventoryName_txt.text == "enter part # here")
				{
					inventoryName = "part";
				}else
				{
					inventoryName = inventoryName_txt.text;
				}

				var jpgURLRequest:URLRequest = new URLRequest("jpg_encoder_download.php?name="+inventoryName+".jpg");

				jpgURLRequest.requestHeaders.push(header);
				jpgURLRequest.method = URLRequestMethod.POST;
				jpgURLRequest.data = jpgStream;
				navigateToURL(jpgURLRequest, "_blank");
				showSpinner(false);
				removeChild(bitmap);
			}

			public function showSpinner(p_loading:Boolean):void {
				if(p_loading) {
					addChild(spinner);
					spinner.play();
				} else {
					removeChild(spinner);
					spinner.stop();
				}
			}


		}
	}

PHP:

<?php

if ( isset ( $GLOBALS["HTTP_RAW_POST_DATA"] )) {
	
	date_default_timezone_set('PST');
	$today = date("M-j-Y-H-i-s");
	
	$filename = $_GET['name'];
	
	if ($filename == "part.jpg")
	{
		$filename = "part-".$today.".jpg";
	}
	
	$filepath = "../parts/".$filename;
	
	// get bytearray
	$im = $GLOBALS["HTTP_RAW_POST_DATA"];
	
	// add headers for download dialog-box
	header('Content-Type: image/jpeg');
	header("Content-Disposition: attachment; filename=".$filename);
	
	$fd = fopen($filepath,"w");
	fputs($fd,$im);
	fclose($fd);
	
	echo $im;
	
}  else echo 'An error occured.';

?> 

Credits:

Webcam AS3 code adapted from GK Sinner and Adobe: link

Encoding and passing the bitmap data to PHP for download adapted from Henry Jones: link

The rest was figured out by experimentation.

Designed By Dave Deriso © 2010