Fixing Image#getRGB()

I have encountered a problem when implementing a nine-patch painter for MIDP 2.0, most of my graphics where left transparent for no-reason. A nine-patch is an image with a flexible center row, and a flexible center column. Most useful when doing themed UI, as a single image can be used to draw buttons, and boxes of any sizes.

The four corners are coped as is, the four borders scaled in a single direction, and the center is scaled in both directions. Since MIDP do not support image scaling this must be implemented by hand using the ARGB values fetched using Image#getRGB(). The documentation is quite straight forward, but fail to mention one pecularity in many implementation…

Clearing unwanted data

I want to create the target image in a single int[] array to reduce memory usage. No problem copying image data into this structure, it is just what the quite straightforward API is designed to do:

public void getRGB(int[] rgbData,
                   int offset, int scanlength,
                   int x, int y,
                   int width, int height)

Unfortunately the documentation fails to mention that many implementations will not as expected just ignore data in rgbData that is not copied. Instead zeroes, or transparent pixels, will be filled in for any image data that has not been requested on a per row basis. I dare anyone to find where this is mentioned in the MIDP spec.

A solution

The solution is to write your own wrapper method for Image#getRGB() that copies just a single row of image data at a time, and the requested scanline length must be lied about to avoid having the remainder of lines filled with zeroes. Here is tho code ready for copy and paste:

public class ImageUtils {
    public static void getRGBFromImage(Image image, int[] argbData, int offset,
            int scanline, int x, int y, int width, int height) {
        for (int row = 0; row < height; row++) {
            image.getRGB(argbData, offset, width, x, y + row, width, 1);
            offset += scanline;
        }
    }
}

Leave a Reply