Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Augmented Reality on Android: Prepping the Camera and Compass : Page 2

Learn how to implement the first two elements of an Augmented Reality engine (the camera and the Compass) on Android.


advertisement

The Custom Camera View

The first step in implementing Augmenting Reality is finding your field of view. This requires activating the camera on your device (in this example, T-Mobile's G1). In this tutorial, you will create a custom surface view on which you'll load the camera preview.

First, you need to request permission to use the camera in your application. Do this by adding the following line just inside the <application> header in your Manifest.xml file.

<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> <uses-permission android:name="android.permission.CAMERA" /> <!--...other stuff goes here...--> </application>



Android's camera object requires a surface view on which to draw its captured frames. To that end, you will create your own custom SurfaceView and hand it off to the camera. The following code creates the view inside the onCreate function of your activity (always called on startup and when your activity is resumed):

public void onCreate(Bundle savedInstanceState) { try{ super.onCreate(savedInstanceState); cv = new CustomCameraView( this.getApplicationContext()); FrameLayout rl = new FrameLayout( this.getApplicationContext()); setContentView(rl); rl.addView(cv); } catch(Exception e){} }

Nothing tricky here: you're creating a custom view, adding it to a frame layout, and finally setting this frame layout as the main view for your activity. Before compiling it (which won't work yet anyway), you need to define the CustomCameraView class as follows:

public class CustomCameraView extends SurfaceView { Camera camera; SurfaceHolder previewHolder; public CustomCameraView(Context context) { super(context); } }

Now that you can at least compile the example thus far, it's time to add some camera code.

First, you have to define a surface listener. Because the camera object takes a surface holder, you may assume that when your activity starts up you can create a surface view and immediately stuff it into the camera. Sadly, despite having its constructor called, the surface isn't actually in a state where you can use it just yet. To get around this timing issue, you will register a surface listener and hand it off to the camera when its surfaceCreated method gets called. Here's the real base constructor for your custom view, which this tutorial covers quickly before getting into the surface listener:

public CustomCameraView(Context ctx) { super(ctx); previewHolder = this.getHolder(); previewHolder.setType (SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); previewHolder.addCallback(surfaceHolderListener); }

Next, you'll pull out your Surface holder as a class member and then register a surface listener with it. Again, don't try to compile this just yet, you'll need to define that surfaceHodlerListener object first.

Listening to the Surface Holder

Here is the inline code for the surfaceHolderListener object:

SurfaceHolder.Callback surfaceHolderListener = new SurfaceHolder.Callback() { public void surfaceCreated(SurfaceHolder holder) { camera=Camera.open(); try { camera.setPreviewDisplay(previewHolder); } catch (Throwable ){ } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Parameters params = camera.getParameters(); params.setPreviewSize(w, h); params.setPictureFormat(PixelFormat.JPEG); camera.setParameters(params); camera.startPreview(); } public void surfaceDestroyed(SurfaceHolder arg0) { camera.stopPreview(); camera.release(); } };

When the surface has been created, your callback's surfaceCreated method will be invoked. At that point it's safe to fetch an instance of the device's camera by calling Camera.open() before running setPreviewDisplay and handing off an instance of the surface holder you stashed aside in the view's constructor. Remember; until surfaceCreated is called, you don't actually have a functional surface holder. Passing the holder into the camera object before this call will cause the camera object to throw inexplicable exceptions.

Figure 1. Preview on T-Mobile myTouch: If you're using a G1, you might find the preview is rotated on its side.
When the surface changes, you'll have to tell the camera what the new preview drawing rectangle should look like. You do this in the surfaceChanged method. You'll pull the parameters out of the camera instance, change the format and size, and then pass the parameter back in. When you've done that, you'll call startPreview and away you go!

Your results may vary depending on what device and firmware you're running. If you're running the preview in an emulator and you see a 3D box floating over a checkered background, don't despair. In lieu of any actual camera data, the emulator is drawing a stock animation to show you where the camera preview would be. Also, if you're using a G1, you might find the preview is rotated on its side (see Figure 1). You will need to apply image translation or some creativity to get this rendering correct.

Congratulations! You've now got a working camera view. It's time to start pulling in the information you'll need to actually render data on top of this camera view.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap