Image Rotation in j2me
by raimon on Aug.26, 2009, under j2me
Lately I’ve been creating some low level image functions for Java ME just to see if low level bitmap manipulation was way too slow for doing it on real time on Java ME or it was, at least, usable. I’ll publish more functions but I’ll start with Image Rotation.
In Java ME is easy to rotate images if you want to rotate by an angle multiple of 90° but it doesn’t provide any mechanism to rotate it by an arbitrary angle (yes, ok… you could do the same using the Mobile 3D API)
I created a small function that fills that gap and allows image rotation by any angle. The resulting image will have the same size as the original (watch out for the corners..)
-
int sw = src.getWidth();
-
int sh = src.getHeight();
-
int[] srcData = new int[sw * sh];
-
-
src.getRGB(srcData, 0, sw, 0, 0, sw, sh);
-
int[] dstData = new int[sw * sh];
-
-
int isa = (int) (256 * sa);
-
int ica = (int) (256 * ca);
-
-
int my = - (sh >> 1);
-
for(int i = 0; i < sh; i++) {
-
int mx = - (sw >> 1);
-
for(int j = 0; j < sw; j++) {
-
int srcx = ( mx * ica + my * isa) >> 8;
-
int srcy = (-mx * isa + my * ica) >> 8;
-
-
srcx += sw >> 1;
-
srcy += sh >> 1;
-
-
if(srcx < 0) srcx = 0;
-
if(srcy < 0) srcy = 0;
-
if(srcx > sw - 1) srcx = sw - 1;
-
if(srcy > sh - 1) srcy = sh - 1;
-
-
dstData[j + i * sw] = srcData[srcx + srcy * sw];
-
-
mx++;
-
}
-
my++;
-
}
-
-
g.drawRGB(dstData, 0, sw, 0, 0, sw, sh, true);
-
}
If we move all the calculations that doesn’t need to be done in the inner loop to the external loop we will have a speed improvement:
-
int sw = src.getWidth();
-
int sh = src.getHeight();
-
int[] srcData = new int[sw * sh];
-
-
src.getRGB(srcData, 0, sw, 0, 0, sw, sh);
-
int[] dstData = new int[sw * sh];
-
-
int isa = (int) (256 * sa);
-
int ica = (int) (256 * ca);
-
-
int my = - (sh >> 1);
-
for(int i = 0; i < sh; i++) {
-
int wpos = i * sw;
-
-
int xacc = my * isa - (sw >> 1) * ica + ((sw >> 1) << 8);
-
int yacc = my * ica + (sw >> 1) * isa + ((sh >> 1) << 8);
-
-
for(int j = 0; j < sw; j++) {
-
int srcx = (xacc >> 8);
-
int srcy = (yacc >> 8);
-
-
if(srcx < 0) srcx = 0;
-
if(srcy < 0) srcy = 0;
-
if(srcx > sw - 1) srcx = sw - 1;
-
if(srcy > sh - 1) srcy = sh - 1;
-
-
dstData[wpos++] = srcData[srcx + srcy * sw];
-
-
xacc += ica;
-
yacc -= isa;
-
}
-
my++;
-
}
-
-
g.drawRGB(dstData, 0, sw, 0, 0, sw, sh, true);
-
}
And if we know beforehand the size of the image we want to rotate we could do some extra tricks (for example, here assumes the source image will be 256×256 pixels and will only work with that resolution):
-
int sw = src.getWidth();
-
int sh = src.getHeight();
-
int[] srcData = new int[sw * sh];
-
-
src.getRGB(srcData, 0, sw, 0, 0, sw, sh);
-
int[] dstData = new int[sw * sh];
-
-
int isa = (int) (256 * sa);
-
int ica = (int) (256 * ca);
-
-
int my = - (sh >> 1);
-
for(int i = 0; i < sh; i++) {
-
int wpos = i * sw;
-
-
int xacc = my * isa - (sw >> 1) * ica + ((sw >> 1) << 8);
-
int yacc = my * ica + (sw >> 1) * isa + ((sh >> 1) << 8);
-
-
for(int j = 0; j < sw; j++) {
-
int srcx = (xacc >> 8) & 0xff;
-
int srcy = yacc & 0xff00;
-
-
dstData[wpos++] = srcData[srcx + srcy];
-
-
xacc += ica;
-
yacc -= isa;
-
}
-
my++;
-
}
-
-
g.drawRGB(dstData, 0, sw, 0, 0, sw, sh, true);
-
}
These functions paints the rotated image in a Graphics object directly, but doing some minor changes it could generate a new Image with the content:
* Change the function declaration to:
* Replace the drawRGB call with:
Feel free to use it for whatever you want but it would be nice if you drop me a line and put me somewhere in the credits
November 9th, 2009 on 9:39 am
this is a nice code, but why you always put
g.drawRGB(dstData, 0, sw, 0, 0, sw, sh, true);
you must just return an image
March 3rd, 2010 on 5:51 pm
Hey many thanks for this….
I was thinking in the same direction for rotation but I had some doubts in calculation. Thanks for this calculations.
I’m doing animations in J2ME 2D. This will be very helpful in my future work.
Let’s keep in touch and share each others UI Development experience in J2ME
March 8th, 2010 on 8:40 am
using j2me how can we rotate a graphics object??
March 16th, 2010 on 7:40 pm
how well does this work with non-square images - like a typical image of 4:3 ratio - say 320×240 - will it return an image that is 240×320? thanks!