Recently I needed the ability to change colors of a picture in real-time. I was developing a game where I needed to paint the player costumes many times within the game. I have researched on the internet and didn’t find any J2ME code available.
I digged all around for an algorithm to do that and found a way to do it.
After reading some codes that did the trick in other languages, I finally figured out how to create a routine to change the colors. The basics behind it is the following:
The MIDP 2.0 API has the ability to extract an array of RBG data from an image by calling the Image’s getRGB() method. This method takes the following parameters:
getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)
Where:
rgbData– an array of integers in which the ARGB pixel data is storedoffset– the index into the array where the first ARGB value is storedscanlength– the relative offset in the array between corresponding pixels in consecutive rows of the regionx– the x-coordinate of the upper left corner of the regiony– the y-coordinate of the upper left corner of the regionwidth– the width of the regionheight– the height of the region
So, to get all image data you need:
int[] raw = new int[image.getWidth() * image.getHeight()]; image.getRGB(raw, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
What you have now is an array of integers representing each pixel of the image in the AARRGGBB format where RR is red, GG is green, BB is blue and the leading AA is alpha). The alpha attibute defines the opacity of that particular pixel and 00 means completly transparent and FF (255) means completly opaque (solid).
So, to change colors we need to change all pixels that matches an RGB value regardless of what the alpha byte is. To do that we need to “mask” the pixel value with the “&” operator. The first mask we need is to extract (and later on preserve) the alpha value. This mask is 0xff000000 and, as you probably noticed, the ff matches the AA position on the integer (it is the leftmost byte on the integer).
Once we have the alpha value, we need to mask the integer again to extract the RGB color. The mask to do that is the opposite of the previous mask: 0×00ffffff. This mask drops the leftmost byte and extracts the desired RGB value.
Now that you have the alpha value and the RGB value, all you need to do is iterate throughout the pixels array and match the RGB color with the one you are replacing. This step is illustrated on the following snippet:
// check each color to replace
for (int j = 0; j < maskedOldColor.length; j++) {
if (currentMaskedPixel == maskedOldColor[j]) {
raw[i] = (currentPixel & alphaOnlyBitmask) | maskedNewColor[j];
break;
}
}
Well, I think you got the idea. Anyway, this is my first post and I’d like to know what you think about it so please: comment it!
Regards,
Felipe.
August 30, 2006 at 9:42 am |
Hi, This seems to be very interesting.. but I m not able to understand the code snippet u have written here. Can u please send me the code with example? It would be very nice of you if you could send.
Thanks in advance,
Priya
August 30, 2006 at 5:21 pm |
psm,
Just e-mailed you what you requested. Best regards!
Felipe.
September 1, 2006 at 9:46 am |
Hi,
How can i find RGB value of any image in MIDP1.0,where u have no
getRGB() method.Can you give some idea how to find RGB value for MIDP1.0.
Thanks
September 1, 2006 at 11:22 am |
abhay,
Thanks for visiting my blog.
Unfortunatelly I have no ideas on how you could mimic getRGB() in
MIDP1. I’ll try to search for something and if I found anything, I’ll
let you know ok?
Take care,
Felipe.
November 6, 2006 at 12:25 am |
I used your approach in a small j2me client recently that tried to send and image of what the user had drawn on a canvas with a stylus. Unfortunately the phone I worked with, was very limited (very few JSRs) and so I eneded up reading the RGB values off each pixel on the canvas and sent it over sockets to the server driving the interactive screen where it’d be displayed. I ended up sending a string like this RR,GG,BB,RR,GG,BB … so the image was painted pixel by pixel on arrival… very inefficient i’m sure but it saved my day. I found your article very helpful … thanks for sharing this.
November 6, 2006 at 1:08 am |
Thanks for your comment! Those kinds of feedback is what
get me going, really. I appreciated you had used my article and it was
worth for you.
February 23, 2007 at 2:05 pm |
I think there’s an issue in your solution.
If i try to mask a value like red (0xff000000) everything works fine.
But if i try to mask another value, to extract the alpha value, i get a wrong value.
For example:
int p=0xa2e3ffff; // ARGB value of a pixel
int c2=p & 0×00FFFFFF; // extracting color…OK
int a= p & 0xff000000;//extracting alpha…wrong
a is actually: ffffffffa2000000 instead of a2000000
What’s wrong with it?
March 12, 2007 at 12:49 pm |
Hi,
thanks for the article,
can you mail me the full code,
thanks in advance,
regards,
arvind
March 22, 2007 at 7:15 am |
Hi,
I have read your article .
It is very good.
I am developing application in which i am sending the RGB values of pixel from server (P.C.) to j2me.
But performance is very slow.
Can You give me your full code and suggestions for my application .
Thank You.
mail : gtemgire@yahoo.co.in
August 26, 2008 at 6:52 pm |
Hi Felipe,
Thanks for this nice article, very nice.
One thing i am into right now is , i need to convert an image ( color or black& white) into golden and silver image, i hope u r getting what i am looking for.
I will really appricieate if you can let me know how that can be achived.
Thanks in advance,
Kanwar
January 2, 2009 at 4:14 am |
I wl b very thankful 3 u if u provide the full program for this .
May 6, 2009 at 12:48 pm |
Hi,
The above example is working fine in simulator. if i install it in real device Nokia 6600 the getRGB() method is not working for large .png image like size (88X57) but it is working fine for small image.
Pls give me some idea how to use getRGB() for large image.
May 12, 2009 at 2:37 pm |
Thanks you ,i am looking solution for this problem from long time but i can not find such approch ,i hope you can email me the code example please.
September 21, 2009 at 7:57 pm |
hi Felipe if it wouldn’t be too much to ask i need this exact thing for a project am currently working. Trust me i have searched for quite for this. It’s a nice thing you putting this out.