Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Posts: 39
Registered: ‎05-26-2009
My Device: BlackBerry Storm 9550

How to convert an Image object to EncodedImage or Bitmap?

Hello,

I'm  trying to convert an Image object (javax.microedition.lcdui.Image) to an EncodedImage or Bitmap object so that it can be displayed in a regular BitmapField. The reason the object is an Image is because it needs to be run through a resizing function that scales it down and applies bicubic filtering to it. The function only takes and returns an Image object, since I found it on a J2ME website. I tried adapting it to work with a Bitmap but Bitmap.getARGB() is not interchangeable with Image.getRGB() in this instance, since getARGB also gives an alpha channel and the resizing function is only expecting three channels. I couldn't modify the resizing function to skip the alpha channel and just output FF as the alpha value.

 

So my only solution here is to convert the resized and filtered Image returned from the resizing function to a Bitmap or EncodedImage that I can display in my BitmapField. Seaching has not turned up very many useful results since "convert image to bitmap" obviously isn't very specific.

 

Does anyone know how I can do this? Or better yet, does anyone think they would know how to modify the function to skip the alpha channel? This would definitely be preferable since I wouldnt't have to spend so much processing time resizing, fitering, and then converting the image.

 

Thanks

Developer
Posts: 39
Registered: ‎05-26-2009
My Device: BlackBerry Storm 9550

Re: How to convert an Image object to EncodedImage or Bitmap?

[ Edited ]
I guess it would be helpful if I posted the resizing function... here is the modified version that takes and returns a bitmap. When I run it in the simulator, the BitmapField is empty, presumably because this function is spitting out invalid bitmap data(rawOutput array only contains three channels instead of the four that setARGB is expecting).

public Bitmap resampleImage(Bitmap orgImage, int newWidth, int newHeight)
{

int orgWidth = orgImage.getWidth();
int orgHeight = orgImage.getHeight();
int orgLength = orgWidth * orgHeight;
int orgMax = orgLength - 1;

int[] rawInput = new int[orgLength];
orgImage.getARGB(rawInput, 0, orgWidth, 0, 0, orgWidth, orgHeight);

int newLength = newWidth * newHeight;

int[] rawOutput = new int[newLength];

int yd = (orgHeight / newHeight - 1) * orgWidth;
int yr = orgHeight % newHeight;
int xd = orgWidth / newWidth;
int xr = orgWidth % newWidth;
int outOffset = 0;
int inOffset = 0;

// Whole pile of non array variables for the loop.
int pixelA, pixelB, pixelC, pixelD;
int xo, yo;
int weightA, weightB, weightC, weightD;
int redA, redB, redC, redD;
int greenA, greenB, greenC, greenD;
int blueA, blueB, blueC, blueD;
int red, green, blue;

for (int y = newHeight, ye = 0; y > 0; y--)
{
for (int x = newWidth, xe = 0; x > 0; x--)
{

// Set source pixels.
pixelA = inOffset;
pixelB = pixelA + 1;
pixelC = pixelA + orgWidth;
pixelD = pixelC + 1;

// Get pixel values from array for speed, avoiding overflow.
pixelA = rawInput[pixelA];
pixelB = pixelB > orgMax ? pixelA : rawInput[pixelB];
pixelC = pixelC > orgMax ? pixelA : rawInput[pixelC];
pixelD = pixelD > orgMax ? pixelB : rawInput[pixelD];

// Calculate pixel weights from error values xe & ye.
xo = (xe << 8) / newWidth;
yo = (ye << 8) / newHeight;
weightD = xo * yo;
weightC = (yo << 8) - weightD;
weightB = (xo << 8) - weightD;
weightA = 0x10000 - weightB - weightC - weightD;

// Isolate colour channels.
redA = pixelA >> 16;
redB = pixelB >> 16;
redC = pixelC >> 16;
redD = pixelD >> 16;
greenA = pixelA & 0x00FF00;
greenB = pixelB & 0x00FF00;
greenC = pixelC & 0x00FF00;
greenD = pixelD & 0x00FF00;
blueA = pixelA & 0x0000FF;
blueB = pixelB & 0x0000FF;
blueC = pixelC & 0x0000FF;
blueD = pixelD & 0x0000FF;

// Calculate new pixels colour and mask.
red = 0x00FF0000 & (redA * weightA + redB * weightB + redC * weightC + redD * weightD);
green = 0xFF000000 & (greenA * weightA + greenB * weightB + greenC * weightC + greenD * weightD);
blue = 0x00FF0000 & (blueA * weightA + blueB * weightB + blueC * weightC + blueD * weightD);

// Store pixel in output buffer and increment offset.
rawOutput[outOffset++] = red + ((green | blue) >> 16);

// Increment input by x delta.
inOffset += xd;

// Correct if we have a roll over error.
xe += xr;
if (xe >= newWidth)
{
xe -= newWidth;
inOffset++;
}
}

// Increment input by y delta.
inOffset += yd;

// Correct if we have a roll over error.
ye += yr;
if (ye >= newHeight)
{
ye -= newHeight;
inOffset += orgWidth;
}
}
Bitmap bitmap = new Bitmap(newWidth, newHeight);
bitmap.setARGB(rawOutput, 0, newWidth, 0, 0, newWidth, newHeight);
return bitmap;
}

}

 

Message Edited by Andiamo on 07-04-2009 08:09 PM
Developer
Posts: 39
Registered: ‎05-26-2009
My Device: BlackBerry Storm 9550

Re: How to convert an Image object to EncodedImage or Bitmap?

In lieu of a way to use this function I've tried a whole mess of other methods to smooth out the resized image and nothing has worked. I got excited after finding a page on the BlackBerry developer site that talks about a scaleInto method belonging to the Bitmap class, along with different interpolation filters, but it turns out those are coming in OS 5.0. Short of offloading image processing to my server-side code I don't know what else I can do.
Any other ideas would be helpful.

Developer
Posts: 132
Registered: ‎02-11-2009
My Device: Not Specified

Re: How to convert an Image object to EncodedImage or Bitmap?

Why do you say getARGB() is not interchangeable with getRGB() ? If you don't care about the alpha chaneel, maybe something like this is enough?

 

for (int i = 0; i < array.length; i++) {

    array[i] = array[i] & 0x00FFFFFF;

}

 

Maybe you need to bitwise shift? I'm not sure as I haven't looked at the byte ordering. But both getRGB and getARGB use 1 int per pixel, there should be a way to convert in a for loop.

 

Cheers, Barak