Archive for the ‘HOWTO’ Category

Android Color Banding

Many Android programmers encounter severe color banding on devices like the Nexus One. For example, here is a radial gradient in an app I wrote this morning.

Banding on a Nexus One

There is an awful lot of misinformation out there, for example I see many people advocating dithering as a solution. Here is my app with dithering enabled:

Nexus One with Dithering

This is better, but won’t look so hot with many bitmaps. The correct solution is to take note of the format. As shown in the above images, Android’s default format is PixelFormat.OPAQUE. You can change this in a few ways. One way is to create a custom theme and set android:windowBackground to a color.

Another solution is to programmatically call Window.setFormat(PixelFormat.RGBA_8888).

The end result:

Eliminating Color Banding on the Nexus One

Sample code:

public class MyActivity extends Activity {
  @Override
  public void onAttachedToWindow() {
    super.onAttachedToWindow();
    Window window = getWindow();
    // Eliminates color banding
    window.setFormat(PixelFormat.RGBA_8888);
  }
}

Win 7 Printing to Airport Printer

We have a combination of Mac and Windows machines in our house, and I was unable to get a new Windows 7 64-bit machine to print. The printer is shared using an Airport Extreme Base Station.

I downloaded Bonjour for Windows and it immediately detected the printer. Everything seemed OK, but printing always failed.

This led to many hours of failed searching and troubleshooting. I found many people have the same problem, and many solutions being offered. Nothing worked, until I noticed the “here” link:

64-bit Bonjour

With those highlighted circles, it seems painfully obvious. But the “download” button is more prominent, so I didn’t read the text. Based on the number of people I encountered having the exact same problem, I must not be the only one to miss this.

The real kicker is the fact that 32-bit Bonjour fails to warn you if you install it on a 64-bit PC. It happily finds the printer, leading to a false sense of success.

One last tip — if Bonjour can’t find the driver, first plug the printer directly into your PC. Windows should be able to download the right driver.

Custom HTTP Headers with GWT RPC

Prior to GWT 2.0, there was no easy way to add custom HTTP headers when making remote procedure calls. The new RpcRequestBuilder in GWT 2.0 makes it easy to add custom headers.

// start with a custom RpcRequestBuilder
RpcRequestBuilder reqBuilder = new RpcRequestBuilder() {
  @Override
  protected RequestBuilder doCreate(String serviceEntryPoint) {
    RequestBuilder rb = super.doCreate(serviceEntryPoint);
    rb.setHeader("username", "sookie_stackhouse");
    return rb;
  }
};

// as with any other RPC, use GWT.create(...) to generate the client proxy
MyServiceAsync service = (MyServiceAsync) GWT.create(MyService.class);

// all client proxies also implement ServiceDefTarget
((ServiceDefTarget) service).setRpcRequestBuilder(reqBuilder);

// make calls as normal
service.doFunAndInterestingThings();

PNG Optimization

I am creating a large number of PNG files for an Android application and need to make the images as small as possible without losing quality.

Missouri

After quite a bit of experimentation, I settled on these steps.

  1. Create the original images in Illustrator
    • Use a limited number of colors
    • Avoid transparency
    • Avoid gradients
    • Create the images in the desired dimensions, 320×480 in my case (to avoid scaling artifacts when exporting)
  2. Export to 320×480 PNG files
  3. Use Gimp to convert to Indexed colors (Image -> Mode -> Indexed)
    • Generate optimized palette
    • Maximum number of colors = 48 (this works well for my particular images — it does NOT work well if you have gradients)
    • No color dithering
  4. Use PNGCrusher to reduce file size even more

PNGCrusher only helps a tiny bit since I already optimized in Gimp, but it can produce pretty dramatic results for non-optimized PNG files.