Posted on July 29, 2009 by Jimmy K. in
Tutorials
Have you noticed the two webcams located in the upper-right corner of this site? Those webcams are being monitored and uploaded using an Adobe AIR application, stored in a MySQL database and controlled with a PHP backend. I’m going to show you the bare bones approach to getting an image from your webcam onto your website.
First, you are going to need to create a SWF file in Adobe Flash and place the following code on the main timeline. It is known to be bad practice to place code on the main timeline, so if you’re comfortable with classes, please feel free to create a class for it.
Update: You’re also going to need to download the
adobe.images package from Adobe because this tutorial utilizes the
JPEGEncoder class.
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.media.Camera;
import flash.media.Video;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLLoader;
import flash.net.URLVariables;
import flash.utils.ByteArray;
import flash.utils.setTimeout;
import com.adobe.images.JPGEncoder;
var UPLOAD_TIMEOUT:uint = 2000;
var aBitmapByteArray:ByteArray;
var iUploadTimeout:uint;
var oCamera:Camera;
var oJPGEncoder:JPGEncoder;
var oVideo:Video;
jInitCamera();
/* Initializes the camera. */
function jInitCamera() {
try {
this.oCamera = Camera.getCamera();
this.oCamera.setMode(640, 480, 15);
this.oCamera.setQuality(0, 100);
this.oVideo = new Video(640, 480);
this.oVideo.attachCamera(this.oCamera);
this.addChild(this.oVideo);
this.oJPGEncoder = new JPGEncoder(50);
this.iUploadTimeout = setTimeout(jUploadSnapshot, UPLOAD_TIMEOUT);
trace("Camera has been initialized.");
} catch (oException:*) {
trace("Unable to initialize camera.");
}
}
/* Uploads a snapshot to our web server. */
function jUploadSnapshot() {
// Create a bitmap data object to hold our snapshot..
var oBitmapData:BitmapData = new BitmapData(640, 480, false, 0x000000);
oBitmapData.draw(this.oVideo);
// Encode the bitmap data, free the memory..
this.aBitmapByteArray = oJPGEncoder.encode(oBitmapData);
oBitmapData.dispose(); oBitmapData = null;
// Create a url request to send the bitmap data..
var oURLRequest:URLRequest = new URLRequest("http://www.yourwebsite.com/upload.php");
oURLRequest.method = URLRequestMethod.POST;
oURLRequest.data = aBitmapByteArray;
// Create a url loader to perform the request..
var oURLLoader:URLLoader = new URLLoader();
oURLLoader.addEventListener(Event.COMPLETE, eUploadComplete, false, 0, true);
oURLLoader.addEventListener(IOErrorEvent.IO_ERROR, eUploadFailed, false, 0, true);
oURLLoader.load(oURLRequest);
}
/* Triggered when the upload completes. */
function eUploadComplete(oEvent1:Event) {
this.iUploadTimeout = setTimeout(jUploadSnapshot, UPLOAD_TIMEOUT);
trace("Snapshot has been uploaded.");
}
/* Triggered when the upload fails. */
function eUploadFailed(oEvent1:IOErrorEvent) {
this.iUploadTimeout = setTimeout(jUploadSnapshot, UPLOAD_TIMEOUT);
trace("Error: Unable to upload snapshot.");
}
Basically, this code initializes the default Camera on your computer, attaches it to a Video object and adds the Video object to the stage. At set intervals (in this case, every two seconds), the code draws the Video object’s bitmap data, converts the bitmap data to a byte array using the JPGEncoder class and uploads it as raw POST data to the “upload.php” file located on your web server.
What do we do with the raw POST data when it’s received by “uploader.php”? Well, we’re going to need to save the POST data as an image. This was actually the most overly-complicated part of the whole process when I was looking for help online. It’s amazing how simple it actually was:
<?php
// Save the fullsize image..
$oHandle = fopen("./fullsize.jpg", "w+");
fwrite($oHandle, file_get_contents("php://input"));
fclose($oHandle);
// Create the thumbnail image..
$oSource = imagecreatefromjpeg("./fullsize.jpg");
$oThumbnail = imagecreatetruecolor(120, 90);
imagecopyresampled($oThumbnail, $oSource, 0, 0, 0, 0, 120, 90, 640, 480);
imagejpeg($oThumbnail, "./thumb.jpg");
// Free the memory..
imagedestroy($oThumbnail);
imagedestroy($oSource);
?>
The above code simply takes the raw POST input and saves it to a file using the
fopen(), file_get_contents(), fwrite() and
fclose() functions. Raw POST data is available to PHP using the “php://input” protocol. I assume it’s sort of like using
file_get_contents() with a “http://” protocol, only.. for PHP-related things. I’m not entirely sure how it works, but it does.
Anyway, after we save the fullsize image, we’re going to scale it down and save a thumbnail. This will help reduce server bandwidth consumption.
As you can see, this tutorial won’t create the exact implementation that I have on my website, but I leave that to your imagination and willingness to create something on your own. I hope this tutorial helps point you in the right direction and also, if you do use the concepts included in this tutorial, please let me know. I would be very interested in seeing another person’s take on it.
Click
here to download the source files.
I’ve finally gotten around to converting the Maximum Attraction and The Ringer movie posters into desktop-friendly wallpapers. The wallpapers come in four different sizes: 1024×768, 1440×900, 1600×1200 and 1920×1200. All four sizes come bundled in a single .zip file.
Click
here to download the Maximum Attraction desktop wallpaper or click
here to download the The Ringer desktop wallpaper.
As you can tell by this very well-put-together poster, Joe Kessen (of
jkessen.com) and I were very busy at Orbit Media Studios this weekend. Tom Jalana (of
tomjalana.com), Joe, Cheryl, the lovely Kiya and myself held multiple photo shoots attempting to get the perfect shots for this year’s movie posters.
Three posters made the cut this year, with many decent runner-ups. They are (in order of production) The Ringer (download hi-res, 1262kb), The Ringer 2 (download hi-res, 985kb) and lastly, Maximum Attraction (download hi-res, 1040kb). Scripts have yet to be written for these future blockbusters, but there is no doubt in my mind that the European suave, Tom Jalana, is up for the challenge.
Movie posters aside, the 48-Hour Film Project turned out to be a bust. No real decisions were made and no one could agree on anything for more than a few minutes. After a long Saturday night, The Orbit Crew, Joe, Cheryl and myself parted our separate ways while Tom, Ed and Kiya went rogue-filmmaker. I’m not sure what the final piece looks like, but I’m sure I can get an advanced copy.
Spread the word that officially licensed The Ringer and Maximum Attraction movie wallpapers are in the works. Be sure to check back later for an update.
Update: We’ve been given permission by Tom Jalana and Ed Sochacki to air this quite interesting film. It’s called Last Resort, and I believe the title is a perfect reflection of the events that unfolded that weekend. Click
here to view the beast.