Take webcam snapshot with OpenLaszlo

Today i have played a bit with my webcam, and tried to make some pictures and save that as jpeg files.

Click here for a demo 😉

At first we must integrate the webcam within a base structure of openlaszlo code. It’s needed to include some ActionScript libraries to realize our little project.
It’s advisable to implement in the base strukture a switch tag for handle the runtime, and also a passthrough tag for including the ActionScript 3 libraries.
This base structure could be look like:

<?xml version="1.0" encoding="UTF-8" ?>
<canvas width="100%" height="100%">
	
	<switch>
		<unless property="$as3">
			<handler name="oninit">
			<![CDATA[
				Debug.error("ActionScript 3 required");
			]]>
			</handler>				
		</unless>
		<otherwise>
		
			<passthrough>				
				import flash.net.*;
				import com.adobe.images.JPGEncoder;
				import flash.utils.ByteArray;
				import flash.display.Bitmap;
				import flash.display.BitmapData;
				import flash.media.Camera;
				import flash.geom.Matrix;
			</passthrough>

		</otherwise>
	</switch>
		
</canvas>

After that we create some views and include a videoview and a camera-tag inside.

<simplelayout axis="y" spacing="0" />
<view name="videoView" width="$once{canvas.imageWidth*2}" height="$once{canvas.imageHeight}">
	<simplelayout axis="x" spacing="0" />
	<view name="videoView" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
		<videoview name="video" oninit="this.stream.broadcast()" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
			<camera name="webcam" show="true" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}" bandwidth="0" picturequality="1.0" />
		</videoview>
	</view>
	
	<view name="snapshot" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}" />
</view>
			
<view layout="axis: x; spacing:0">
	<button text="Take a snapshot" onclick="canvas.takeSnapshot();" width="$once{canvas.imageWidth}" />
	<button text="Save snapshot" onclick="canvas.saveImage();" width="$once{canvas.imageWidth}" />		
</view>

I don’t know what i do wrong, but i have the feeling that the bandwidth and quality changes does not work (using lps 4.9.0). So, i additional change these values within the oninit handler. If you have a tip, or know what’s the problem of that, please contact me 😉
Here now my oninit handler:

<handler name="oninit">
<![CDATA[
	
	// Get the webcam 
	var cam:Camera = Camera.getCamera();
	
	// Specifies the maximum amount of bandwidth that the current outgoing video feed can use, in bytes per second. To specify that Flash Player video can use as much bandwidth as needed to maintain the value of quality , pass 0 for bandwidth . The default value is 16384.
	var bandwidth:int = 0; 
	
	// This value is 0-100 with 1 being the lowest quality. 
	// Pass 0 if you want the quality to vary to keep better framerates
	var quality:int = 100; 
	
	// Set bandwidth and quality
	cam.setQuality(bandwidth, quality);
	
	// Set measurements and framerate
	cam.setMode(canvas.imageWidth, canvas.imageHeight, 30, false); 
	
]]>
</handler>

For taking a snapshot from the webcam, we write a small function:

<method name="takeSnapshot">
<![CDATA[
	// create a new bitmap object
	var tempSnapshot:BitmapData =new BitmapData(canvas.imageWidth, canvas.imageHeight, true, 0x00FFFFFF);
	tempSnapshot.draw(canvas.videoView.videoView.video.getDisplayObject(), new Matrix());
	
	// place the snapshop i a view
	var targetView = canvas.videoView.snapshot.getDisplayObject();
	targetView.addChild(new Bitmap(tempSnapshot));
	
	canvas.setAttribute("shotAvailable", true);	
]]>
</method>	

Further we want save the snapshot at a local machine. Therefore we must convert the snapshot into a image and send it to the client.

In order to convert the snapshot into a image, we need the JPGEncoder ActionScript library from Mike Chambers.
Some days ago i write about, how to integrate this in OpenLaszlo. You will find the article here.
Here now the function for converting the snapshot into a image:

<method name="saveImage">
<![CDATA[
	
	if(canvas.shotAvailable) {
		
		// Take the snapshot movieclip
		var sketch_mc = canvas.videoView.snapshot.getDisplayObject();
		
		// Get the image data from that
		var jpgSource:BitmapData = new BitmapData(sketch_mc.width, sketch_mc.height);
		jpgSource.draw(sketch_mc);
		
		// Create a Jpeg from the image data
		var jpgEncoder:JPGEncoder = new JPGEncoder(85);
		var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);
		
		// Create an URLRequest with the image
		var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
		var jpgURLRequest:URLRequest = new URLRequest("./snapShotHandle.php?name=sketch.jpg");
		jpgURLRequest.requestHeaders.push(header);
		jpgURLRequest.method = URLRequestMethod.POST;
		jpgURLRequest.data = jpgStream;
		
		// Send the image for download
		navigateToURL(jpgURLRequest, "_blank");
	}
	
]]>
</method>	

For saving the image, we use use a small PHP script like:

<?php

// create filename
$filename = date("Y-m-d_H:i:s", time())."_".uniqid(mt_rand(), true).".jpg";

if(isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
	
	// add headers for download dialog-box
	header('Content-Type: image/jpeg');
	header("Content-Disposition: attachment; filename=".$filename);
	echo $GLOBALS["HTTP_RAW_POST_DATA"];

}

?>

That’s all you need…
Click here for a demo 😉

Sourcecode: OpenLaszlo - SnapShot.zip (1070)

If you found some bugs or have some Tips, please contact me.

  1. When you loom a cloth it is very tight. i.e. Canvas When you do it by hand it’s “wicker” looking.

  2. here is a component that can use to take snapshot from falsh

    http://anilmathewm.blogspot.com/2010/07/web-camera-snapshot-flash-actionscript.html

      • tdeuling
      • May 21st, 2011

      Thanks. Here should be the focus on the integration into OpenLaszlo..

  3. Great post, thanks. I signed up to your blog RSS.

  1. No trackbacks yet.