Very poor image scaling in LWUIT? Solved!

Working on a recent project involving the visualization of images from a server on mobile devices' (small) screens, I got in touch with a serious problem: LWUIT has a fast, but very poor scaling algorithm. The quality of the images scaled to be smaller is very poor, as much as texts and numbers cannot be read on the screen. Because I had to solve the problem I looked for a solution and I found the library J2ME Army Knife (http://www.j2mearmyknife.com/) that suppiles several utility classes to manage images.
The really interesting classes that helped me to solve my problem was:

ImageTransformationResize

and

ImageTransformationSmooth

The following function resize an image to a given width and height:

public static Image scaled(Image img, int w, int h)
{
    SmartImage simage =

        new SmartImage(img.getRGB(),
                       img.getWidth(),
                       img.getHeight());

    ImageTransformationResize resizer =
        new ImageTransformationResize();

    resizer.setTargetDimensions(w, h);

    AbstractImage rimage = resizer.process(simage);   

    return Image.createImage(rimage.getRGBData(),
                             rimage.getWidth(),
                             rimage.getHeight());
}

to scale to a smaller ratio use this function:

public static Image scaledSmallerRatio(Image img, int w, int h)
{       
    float hRatio = ((float)h) / ((float)img.getHeight());
    float wRatio = ((float)w) / ((float)img.getWidth());
       
    if(hRatio < wRatio) {
        return scaled(img,
                      (int)(img.getWidth() * hRatio),
                      (int)(img.getHeight() * hRatio));
    } else {
        return scaled(img,
                      (int)(img.getWidth() * wRatio),
                      (int)(img.getHeight() * wRatio));
    }               
}

If you want to scale to a greater image you may need to smooth the resized image in order to reduce the pixellation. You can use the class ImageTransformationSmooth.

The following function makes the smoothing:

public static Image smooth(Image img, int passes)
{
    SmartImage simage =
        new SmartImage(img.getRGB(),
                       img.getWidth(),
                       img.getHeight());

    ImageTransformationSmooth smoother =
        new ImageTransformationSmooth();

    smoother.setMode(ImageTransformationSmooth.FAVOR_QUALITY);
    smoother.setPasses(passes);

    AbstractImage fimage = smoother.process(img);

    return Image.createImage(fimage.getRGBData(),
                             fimage.getWidth(),
                             fimage.getHeight());
}

Note that the above snippets work also on J2ME as well as on BlackBerry (RIM API).I didn't try on Android yet

 

Commenti (1) -

I have been trying all other functions except this one to solve the problem. What an idiot I am!

Aggiungi Commento