Capture BitmapData with JavaScript AIR applications

Filed under: AIR, JavaScript, jQuery

comments (6) Views: 8,236

When it comes to AIR application development, those of us using JavaScript are second class citizens. It's unfortunate, but true. Functionality easily available in Flash or Flex is either missing, or difficult to find (and use) in our apps. One such piece of functionality is the ability to capture screen shots, or bitmap data, for use in other parts of your app. In this post, I'll show you how you too can capture bitmap data using JavaScript, and a sprinkling of AS3.

Before beginning this project you'll need to make sure you've got the image classes available from Adobe's CoreLib project. It's a set of helper classes that's not packaged in with AIR. You can also compile your own if you've got Flash, or Flex. Download the SWF and put it aside for now.

  1. Start by creating a new Aptana AIR project
    • Call it whatever you like, but make sure to include the AIRaliases and jQuery JavaScript files
    • It might also be helpful to include the AIR Introspector file for debugging purposes
  2. Open the main HTML file, usually the same name as your project.
    • Make sure that the AIRAliases and jQuery files are included.
  3. Now's when we'll move the SWF file containing the image classes we'll be using, specifically the JPGEncoder class, into our project
  4. Next we'll need to include the SWF file. To do this we add a new script block, as if were including another JS file. This time the type attribute gets set to application/x-shockwave-flash, while the src attribute points to the location of the SWF in your project.
    
    <script type="application/x-shockwave-flash" src="lib/ImageEncoderLib.swf"></script>
    
    
  5. Open a new script block, and inside it open a jQuery document.ready block. Inside that, place the following two lines.
    
    // binds a click event to the button which fires our screen capture
    $('#snagit').bind('click', snagPic);
    // displays a message to the user where the capture will be saved.
    $('span').html(air.File.desktopDirectory.resolvePath('Images/').nativePath);
    
    
    • Note the use of air.File.desktopDirectory, an AIR property which translates to the location of your desktop based on your operating system.
  6. The last piece of JavaScript code we'll need to add is the snagPic function. Copy this code into your document.ready block as well.
    
    function snagPic() {
    	// gets the user specified filename from an input field
    	var filename = $('#filename').val() + '.jpg';
    	// gets the image quality from an input field
    	var quality = $('#quality').val();
    }
    
    
  7. To the bottom of the snagPic function we'll add the following lines
    
    // built into the AIR runtime
    var bitmapData = new window.runtime.flash.display.BitmapData(550,200, false);
    // the data we want to store as bitmap
    bitmapData.draw(nativeWindow.stage);
    
    
  8. Remember when we added the SWF to our project? Since all AIR applications run inside the Flash player, we're able to use existing, or imported Actionscript 3 classes. While the BitmapData class is built into the AIR runtime, the JPGEncoder class is external.
  9. 
    // the next two lines convert the raw bitmap data into a JPG data.
    var encoder = new window.runtime.com.adobe.images.JPGEncoder(quality);
    var ba = encoder.encode(bitmapData);
    
    
  10. Finally we need to take the JPG data and store it to the file system. The last 5 lines open a filestream and write that data.
    
    // creates an image directory on your desktop, writes the image there
    newImage = air.File.desktopDirectory.resolvePath("Images/" + filename);
    // new filestream
    var fileStream = new air.FileStream();
    // open the file
    fileStream.open(newImage, air.FileMode.UPDATE);
    // use the writeBytes method to store binary data
    fileStream.writeBytes(ba);
    // never forget to close your fileStream
    fileStream.close();
    
    
  11. If you're following along correctly, your HEAD tag should look something like this
    
    <script type="text/javascript" src="lib/air/AIRAliases.js"></script>
    <script type="text/javascript" src="lib/jquery/jquery-1.3.2.min.js"></script>
    <script type="application/x-shockwave-flash" src="lib/ImageEncoderLib.swf"></script>
    <script type="text/javascript">
    	$(document).ready(function(){
    
    		$('input[type=button]').bind('click', snagPic);
    		$('span').html(air.File.desktopDirectory.resolvePath('Images/').nativePath);
    
    		function snagPic() {
    			var filename = $('#filename').val() + '.jpg';
    			var quality = $('#quality').val();
    			var bitmapData = new window.runtime.flash.display.BitmapData(550,200, false);
    			bitmapData.draw(nativeWindow.stage);
    			var encoder = new window.runtime.com.adobe.images.JPGEncoder(quality);
    			var ba = encoder.encode(bitmapData);
    			newImage = air.File.desktopDirectory.resolvePath("Images/" + filename);
    			var fileStream = new air.FileStream();
    			fileStream.open(newImage, air.FileMode.UPDATE);
    			fileStream.writeBytes(ba);
    			fileStream.close();
    		}
    	});
    </script>
    
    
  12. Last but not least we need to add our interface elements. There's nothing special here. Copy and paste these lines into your BODY tag
    
    <label for="fileName">File name</label>
    <input type="text" id="filename" value="myImage" size="15" />
    
    <label for="quality">Quality</label>
    <input type="text" id="quality" value="100" size="3" maxlength="3"/>
    
    <input type="button" id="snagit" value="Pic me!" />
    <br /><br />
    Images will be saved to: <br /> <span></span>
    
    
  13. Run your project and you should be able to tweak the filename, and image quality of your capture bitmap image.
  14. A full reference to the available classes in Actionscript 3 can be found here. All of these classes should be directly available in AIR, you just might have to fiddle around to find them.
  15. And finally you can download the full source code of this project

So, while being a JavaScript AIR developer is a little harder in some cases, we can get most (if not all) of what we want accomplished with a little leg work and some perserverance.

Amazon logo

If this article was interesting, or helpful, or even wrong, please consider leaving a comment, or buying something from my wishlist. It's appreciated!

Related Posts


comments powered by Disqus