For the life.turns blipfoto project we wanted to quickly push out a feature to be able to add to the fun.

The extension would be that an image had is shown on top of a camera ‘preview’, so you could align the person on your screen with one of the prescribed poses. The trouble started because the final picture would be a lot different from the image you saw in the preview. As the alignment over at blipfoto had to be as good as possible, this was a big problem.

Making some sort of preview-screen based upon the example is trivial, although if you are using 1.5 (api lvl 3) you cannot use the newest version. The main difference is getSupportedPreviewSizes(), that doesn’t exist. So getOptimalPreviewSize() doesn’t work here, and basically you have no setPreviewSize() in the surfaceChanged(). But the basics are there.

Well, if you ignore the difference in surfaceChanged, it all seems to work just fine. All we have to do now is add a button or use the camera button to call the “take a picture” function, aptly named “takePicture()”. The former isn’t a problem, the latter I did like this:

	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_CAMERA) {
			if (!bIsPictureTaking) {
				return true;
				//ignore buttons while taking pics.
				return true;
			return super.onKeyDown(keyCode, event);

It’s not complete, but that’s the basic proof of concept. Now the onClick we call is ofcourse the same onClick you got set as onclicklistener for the button you might have made so it’s all a bit of patchwork, but again, this is to keep this example basic. Now for the code to take the picture:

	public void onClick(View v) {
		myCamera.takePicture(null, null, this);//nulpoint

If you want to use possible autofocus, you can take a look over here

But now for the real trouble: It seems that on the G1 the standard previewsize you get is 320 x 480, while the picture size is something like 1536 x 2048. A quick thinker sees that the preview is 2:3, while the picture is ofcourse 3:4. Yes. Trouble. The Motorola Milestone (european Droid) does NOT have this difference. (And do not look at the virtual machine in the SDK, it’s completely useless with the ‘camera’.)

Now because the preview has to be defaulted to some sort of standard, and we cannot get a list of these sizes in the old SDK, there is no real solution sadly. What you can learn from this, is that the difference in the vertical preview is 3/4 * 2/3.

In the life.turns case this means that the overlay on the preview has to be stretched with 9/8, but you can calculate this difference using this code:

	Camera.Parameters parameters = myCamera.getParameters();
	int picH = parameters.getPictureSize().height;
	int picW = parameters.getPictureSize().width;
	int preH = parameters.getPreviewSize().height;
	int preW = parameters.getPreviewSize().width;
	float scale = ((float)(picH*preW)) / ((float)(picW*preH));

Not pretty. But development time for this feature was really short, so shortcuts had to be taken :). I located this in the onSurfaceChange function of the surfaceview that would make the cameraPreview, because all these facts had to be known there, but I guess you can do this anyplace you can get your fingers on those parameters :)

Comments are closed.