Prepare for Android Ice Cream Sandwich

Ice Cream Sandwich is coming and it seems there are a couple of changes for us developers. The new Android version will bring phones and tablets closer together. Google has put a tutorial online so we can start preparing us.

The Ice Cream Sandwich release will support big screens, small screens, and everything in between. This is the way Android will stay from now on: the same version runs on all screen sizes.

As for now, a Honeycomb application runs only on big screens and it didn’t need to think about smaller screens. In ICS, the developer will need to prepare for different layouts.

In the tutorial, Google gives tips on how you can make a layout that works well on both type devices.

Developers can already start to include some of the changes. ICS will be available around the beginning of November. Some say the Nexus Prime will be launched on November 3th and this device will have ICS.

Wondering how Basic4Android will cope with those changes.

We’ll keep an eye on that!

See the Google tutorial for more tips: http://android-developers.blogspot.com/2011/09/preparing-for-handsets.html

Installing Windows 8 Preview in Virtual Box 4.1

Today Microsoft released a preview of windows 8. Naturally we do want to test it but knowing Microsoft we do not want to mess up our existing machines 🙂

So we install it on a virtual machine. As for now it does not work on VMWare. However, VMWare 8 will come out in a couple of days and it should support Windows 8.

As for now, we are going to use virtual box 4.1.

Note: click on the pictures if you want to see the full screenshot.

First download the files:

Virtual box:
http://download.virtualbox.org/virtualbox/4.1.2/VirtualBox-4.1.2-73507-Win.exe
Windows 8 Developer Preview:
http://wdp.dlws.microsoft.com/WDPDL/9B8DFDFF736C5B1DBF956B89D8A9D4FD925DACD2/WindowsDeveloperPreview-64bit-English-Developer.iso

Read the full Installation Guide…

Augmented Reality: bring out the Bat-Signal!

After playing around with AR, I’ve decided to make a B4A library from an existing AR library: NyARToolkit (http://nyatla.jp/nyartoolkit/).

Some functions did not work properly and I had to rewrite some of them so they could fit in a B4A library. I also wanted to use the GLSurfaceView from Andrew Graham in basic4android. To do this, I had to extract everything that had to do with 3D and OpenGL. It took some fiddling around, but I think I cracked it.

With a couple of lines in b4a, I can now find the markers and put a 3D model on top of it. The speed and accuracy of the NyARToolkit is ok and it is certainly possible to make some fun projects.

Just to play around, I’ve put one of my favorite superheroes on top of the marker. Batman to the rescue!

Example of the code needed to get the markers:

Sub ABAR_MarkersFound()
	
	Dim Vect As ABARVector2D
	Dim a As Int
	Dim b As Int
	Dim Markers As List
	Markers.Initialize
	Markers = ABAR.GetMarkers()
	Dim corners As List
	corners.Initialize
	Dim Msg As String
	
	FoundMarkers = markers.Size - 1
	For a = 0 To foundMarkers
		
		Mark = Markers.Get(a)
		conf(a) = Mark.Confidence
	
		counter = 0
		Msg = "Marker: " & Mark.ARCodeIndex & CRLF
		Msg = Msg & "x:" & Mark.Center.x & " y:" & Mark.Center.y & CRLF
		Msg = Msg & "Confedence:" & Mark.Confidence & CRLF
		Corners = Mark.Corners
		Vect = Corners.Get(0)
		Msg = Msg & "Corner1=x:" & vect.x & "y:" & vect.y & CRLF
		Vect = Corners.Get(1)
		Msg = Msg & "Corner2=x:" & vect.x & "y:" & vect.y & CRLF
		Vect = Corners.Get(2)
		Msg = Msg & "Corner3=x:" & vect.x & "y:" & vect.y & CRLF
		Vect = Corners.Get(3)
		Msg = Msg & "Corner4=x:" & vect.x & "y:" & vect.y & CRLF
		Markfound = True
		For b = 0 To 15
			tmpresultf(a,b) = Mark.resultf(b)
			tmpcameraRHf(b) = Mark.cameraRHf(b)
		Next
		Msg = Msg & CRLF
			
		useRHfp = True
		drawp = True

		Log(Msg)		
	Next
	glsv.RequestRender
End Sub

Let’s get physical with Basic4Android

One of the libraries I wrote for Basic4Android is ABPhysicsEngine. This is a full 2D Newton engine. Games like ‘Angry Birds’ and ‘Cut the rope’ are made with similar engines. This one is very easy to use within B4A.

For this tutorial you must download version 1.1 of the library from the B4A forum!

Here is a little ‘anti-stress’ game I made with the library in B4A. You have to tap very fast anywhere on the screen and all kind of balls will appear and fall down on the two running Garfields. No winning or prices, but this is for learning purposes anyway.

Let’s get started with the tutorial…

Augmented Reality: Taking away the rainbow

For the Augmented Reality project, I’ll need to grayscale the image.

There are 3 types of grayscaling available in the class but the one I’ll need will be BT709. It turns out it gives the best results for searching glyphs.

It’s a simple conversion but already we have something to take into account when we use Java: the byte type. A byte in java has a value of -128 to 127 instead of 0 to 255. Therefor we will need to do & 0xFF when we return the grayscaled bitmap.

I’ll have to remember this for future calculations on the imageData array!

Here is the class. De imageData is kept in memory as I’ll need those pixels anyway to do the next step: Edge detection!

// Copyright © Alain Bailleul, Alwaysbusy's Corner 2011
//
// Grayscale type values from:
//
// AForge Image Processing Library
// AForge.NET framework
// http://www.aforgenet.com/framework/

import android.graphics.Bitmap;
import android.graphics.Color;

public static class ABImage
{
    //data that will contain the grayscaled pixels
    public byte[] imageData;
    public int width=0;
    public int height=0;
    private double RedCoefficient;
    private double GreenCoefficient;
    private double BlueCoefficient;

    //3 types of grayscaling
    public void SetGrayscaleBT709() {
        RedCoefficient   = 0.2125;
        GreenCoefficient = 0.7154;
        BlueCoefficient  = 0.0721;
    }

    public void SetGrayscaleRMY() {
        RedCoefficient   = 0.5000;
        GreenCoefficient = 0.4190;
        BlueCoefficient  = 0.0810;
    }

    public void SetGrayscaleY() {
        RedCoefficient   = 0.2990;
        GreenCoefficient = 0.5870;
        BlueCoefficient  = 0.1140;
    }

    // create a 8 bit byte array with the pixels of the grayscaled image
    public void FromBitmap( Bitmap image )
    {
        width = image.getWidth();
        height = image.getHeight();

        int[] pixelData = new int[width * height];
        int i = 0;

        image.getPixels(pixelData, 0,width, 0, 0, width, height);

        for (int pixeldatai: pixelData)
        {
             imageData[i++] = (byte) ( RedCoefficient * Color.red(pixeldatai)
                                    + GreenCoefficient * Color.green(pixeldatai)
                                    + BlueCoefficient * Color.blue(pixeldatai));
        }
    }

    //return the grayscale byte array back to a 32 bit bitmap
    public Bitmap ToBitmap()
    {
        int[] pixelData = new int[width * height];
        int i=0;

        for (byte imageDatai: imageData)
        {
            pixelData[i++] = ((255 & 0xFF) << 24) | //alpha
                ((imageDatai & 0xFF) << 16) | //red
                ((imageDatai & 0xFF) << 8 )  | //green
                ((imageDatai & 0xFF) << 0 ); //blue
            }
        return Bitmap.createBitmap(pixelData, width, height, Bitmap.Config.ARGB_8888);
    }
}

Tricking B4A and Java to do byref. How about that!

Neither B4A nor Java support byref arguments nativily. Or do they?

By using this simple trick, you can mimic byref by exploiting their hidden pointer potential.

In Java:

private void Test() {
   //declare the byref value as an array with size 1
   String[] value = new String[1];
   //passing an array is not passing the whole array, but a pointer
   ByrefTest(value);
   //Et voila! the changed value
   System.out.print(value[0]);
}

private void ByrefTest(String rValue[]) {
   // using the pointer, B4A fills the string with our value
   rValue[0] = "Changed in the function!";
}

In B4A:

Sub Activity_Create(FirstTime As Boolean)
   ' dim the byref value as an array with size 1
   Dim value(1) As String
   ' passing an array is not passing the whole array, but a pointer
   ByrefTest(Value)
   ' Et voila! the changed value
   Msgbox( value(0), "")
End Sub

Sub ByrefTest(rValue() As String)
   ' using the pointer, B4A fills the string with our value
   rValue(0) = "Changed in the function!"
End Sub

This will come in handy when I convert some AForge.NET c# code to java, I’m sure!