Tackling Android’s Camera Resolutions

Problem

Anyone who has played with Android knows that form factor is not to be taken lightly.  The platform is available on an ever growing number of devices with a wide variety of resolutions and pixel densities.  This can give developers grief, particularly if they are coming from iPhone dev, where, with few exceptions, the hardware is the same across all  users.  Recently, I was developing an app that made use of the devices camera.  Everything was going swimmingly until my app began crashing on my Nexus S, but not on my Galaxy Tab or the Evo.  After some digging, it became clear that I was trying to set a camera resolution that was not compatible with the Nexus S.

My first go-around seemed simple enough.  I had not hard-coded a resolution, but instead was polling the device for its display size, and using the width and height as my camera resolution [swapping the two if necessary to ensure a ‘portrait’ resolution].  However, there are apparently many phones who’s display resolution is not available as a camera resolution.  Fail.

My thoughts then began to trend toward just setting the highest resolution available as I am sure many do, but that didn’t seem good enough.  I can think of many times wherein a developer may want a SurfaceView that is a particular portion of the screen, and thus a compatible resolution that is close to that size.

Solution

Fortunately after a bit of tinkering, I came up with a solution I am pretty fond of.  Rather than picking the highest resolution and cramming it into a SurfaceView, why not find a resolution that most closely matches the SurfaceView we specified?  That is what I chose to do, using the following algorithm.

 
public int[] findCompatibleResolution(int width, int height) { 
    List<Size> sizes = camera.getParameters().getSupportedPreviewSizes();
    int[] resolution = { 0, 0 };
    int delta = Integer.MAX_VALUE;
    int temp = 0;
    for(Size size : sizes) {
        temp = Math.abs(size.width - width) + Math.abs(size.height - height);
        if(temp < delta) {
            delta = temp;
            resolution[0] = size.width;
            resolution[1] = size.height;
        }
    }
    return resolution;
}



This method takes width and height parameters and looks tries to find a resolution that varies from these the least.  It will then return an int array with the compatible width in [0] and compatible height in [1].

Hope you find this useful!  Please feel free to post questions and I will do my best to get back to them. Also, check out posts, whitepapers, and other great content at http://blog.credera.com

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: