J2ME: Scale an Image to Fit the Screen Size

Posted by & filed under , .

It’s more and more common with the new generation of mobiles nowadays to have a megapixel camera built in the mobile itself. And with that comes the fact that if you ever want to allow your user to select one of the images s/he has captured with this camera (see above) you are dealing with very large images. So if at some point all you want to do is to allow your user to browse through these images one at a time (so you will have to scale the image such that it fits the screen), you will be using a lot of memory for the purpose of showing the user just a 320×240 image!

In such cases, it is good to have a “scaling” function, that reduces the image to just the size of screen, thus reducing the memory consumption and also improving the “painting” time (the time it takes your application to draw the image onto the scren/canvas).

Simply add the following function to your class and invoke it passing it the Image object you want rescaled to the size of the screen:

/**
 * Function used to scale each image down/up to the size of the screen.
 * Adapted from http://forum.benqmobile.com/jive3/thread.jspa?threadID=16310&messageID=66929
 * Note that we rely on the fact that screenWidth and screenHeight are member of this class,
 * already initialized to the size of the screen!
 *
 * @param image Image to scale
 * @return Scaled version of the image, having the width and height equal to the
 * size of the screen.
 */
protected Image createScaledImage( Image image ) {
   final int sourceWidth = image.getWidth();
   final int sourceHeight = image.getHeight();
   final Image sImg = Image.createImage( screenWidth, screenHeight );
   final Graphics g = sImg.getGraphics();
   final int[] lineRGB = new int[sourceWidth];
   final int[] sourcePos = new int[screenWidth]; // cache for x positions
 
   /*
    * Pre-calculate x positions with modified bresenham algorithm
    * http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
    */
   int y = 0;
   int eps = -(sourceWidth >> 1);
   for( int x = 0; x < sourceWidth; x++ ) {
      eps += screenWidth;
      if ( (eps << 1) >= sourceWidth ) {
         if( ++y == screenWidth )
            break;
         sourcePos[y] = x;
         eps -= sourceWidth;
      }
   }
 
   for( int y = 0; y < screenHeight; y++ ) {
      image.getRGB( lineRGB, 0, sourceWidth, 0, y * sourceHeight / screenHeight, sourceWidth, 1 );
      for( int x = 1; x < screenWidth; x++ ) // skip pixel 0
         lineRGB[x] = lineRGB[sourcePos[x]];
      g.drawRGB( lineRGB, 0, screenWidth, 0, y, screenWidth, 1, false );
   }
   return sImg;
}

IMPORTANT: The above function seems to only work when scaling images DOWN!

NOTE: This is an article I’ve brought back to life from my old website — as such it has been around 4 years since I wrote this code so it might not work correctly with the new J2ME standards, since the API’s and JSR’s might have changed. I do not plan on maintaining this code — so please understand that it’s unlikely I’ll post an update on this: it’s simply provided so people who are looking for the old page to still be able to find the code.

One Response to “J2ME: Scale an Image to Fit the Screen Size”

  1. Omolara

    Hello. I found your snippet really helpful. Thanks.